diff --git a/README.rst b/README.rst index f2bdea0..b3bf61c 100644 --- a/README.rst +++ b/README.rst @@ -57,7 +57,7 @@ API v1 Example # regular syntax client = aiosu.v1.Client("osu api token") user = await client.get_user(7782553) - await client.close() + await client.aclose() if __name__ == "__main__": @@ -95,7 +95,7 @@ API v2 Example # regular syntax client = aiosu.v2.Client(client_secret="secret", client_id=1000, token=token) user = await client.get_me() - await client.close() + await client.aclose() if __name__ == "__main__": diff --git a/aiosu/exceptions.py b/aiosu/exceptions.py index c51ed50..da3130d 100644 --- a/aiosu/exceptions.py +++ b/aiosu/exceptions.py @@ -3,7 +3,7 @@ """ from __future__ import annotations -__all__ = ("APIException",) +__all__ = ("APIException", "InvalidClientRequestedError", "RefreshTokenExpiredError") class APIException(Exception): @@ -20,6 +20,17 @@ def __init__(self, status: int, message: str = "") -> None: self.status = status +class RefreshTokenExpiredError(Exception): + """Refresh Token Expired Error + + :param message: error message, defaults to "" + :type message: str, optional + """ + + def __init__(self, message: str = "") -> None: + super().__init__(message) + + class InvalidClientRequestedError(Exception): """Invalid Client Requested Error diff --git a/aiosu/v1/client.py b/aiosu/v1/client.py index 4d2899a..66fdfb1 100644 --- a/aiosu/v1/client.py +++ b/aiosu/v1/client.py @@ -99,7 +99,7 @@ async def __aexit__( exc: Optional[BaseException], traceback: Optional[TracebackType], ) -> None: - await self.close() + await self.aclose() async def _request( self, @@ -475,8 +475,16 @@ async def get_beatmap_osu(self, beatmap_id: int) -> StringIO: data = await self._request("GET", url) return StringIO(data) - async def close(self) -> None: + async def aclose(self) -> None: """Closes the client session.""" if self._session: await self._session.close() self._session = None + + async def close(self) -> None: + """Closes the client session. (Deprecated)""" + warn( + "close is deprecated, use aclose instead. Will be removed on 2024-03-01", + DeprecationWarning, + ) + await self.aclose() diff --git a/aiosu/v2/client.py b/aiosu/v2/client.py index 0663e6d..4d86ee5 100644 --- a/aiosu/v2/client.py +++ b/aiosu/v2/client.py @@ -24,6 +24,7 @@ from ..events import ClientUpdateEvent from ..events import Eventable from ..exceptions import APIException +from ..exceptions import RefreshTokenExpiredError from ..helpers import add_param from ..helpers import append_param from ..helpers import from_list @@ -129,7 +130,13 @@ def check_token(func: F) -> F: async def _check_token(self: Client, *args: Any, **kwargs: Any) -> object: token = await self.get_current_token() if datetime.utcnow().timestamp() > token.expires_on.timestamp(): - await self._refresh() + try: + await self._refresh() + except APIException: + await self._delete_token() + raise RefreshTokenExpiredError( + "Refresh token has expired. Please re-authenticate.", + ) return await func(self, *args, **kwargs) return cast(F, _check_token) @@ -245,7 +252,7 @@ async def __aexit__( exc: Optional[BaseException], traceback: Optional[TracebackType], ) -> None: - await self.close() + await self.aclose() def on_client_update( self, @@ -710,6 +717,7 @@ async def search(self, query: str, **kwargs: Any) -> SearchResponse: Optional, page to get, ignored if mode is ``all`` :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Search response object :rtype: aiosu.models.search.SearchResponse """ @@ -736,6 +744,7 @@ async def get_me(self, **kwargs: Any) -> User: Optional, gamemode to search for :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Requested user :rtype: aiosu.models.user.User """ @@ -754,6 +763,7 @@ async def get_own_friends(self) -> list[User]: r"""Gets the token owner's friend list :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of friends :rtype: list[aiosu.models.user.User] """ @@ -779,6 +789,7 @@ async def get_user(self, user_query: Union[str, int], **kwargs: Any) -> User: Optional, "string" or "id". Type of the user_query :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Requested user :rtype: aiosu.models.user.User """ @@ -806,6 +817,7 @@ async def get_users(self, user_ids: list[int]) -> list[User]: :param user_ids: The IDs of the users :type user_ids: list[int] :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of user data objects :rtype: list[aiosu.models.user.User] """ @@ -834,6 +846,7 @@ async def get_user_kudosu(self, user_id: int, **kwargs: Any) -> list[KudosuHisto Optional, offset of the first score to get :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of kudosu history objects :rtype: list[aiosu.models.kudosu.KudosuHistory] """ @@ -877,6 +890,7 @@ async def __get_type_scores( :raises ValueError: If limit is not between 1 and 100 :raises ValueError: If type is invalid :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] or list[aiosu.models.lazer.LazerScore] """ @@ -927,6 +941,7 @@ async def get_user_recents( Optional, whether to use the new format, defaults to ``False`` :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] or list[aiosu.models.lazer.LazerScore] """ @@ -955,6 +970,7 @@ async def get_user_bests( Optional, whether to use the new format, defaults to ``False`` :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] or list[aiosu.models.lazer.LazerScore] """ @@ -983,6 +999,7 @@ async def get_user_firsts( Optional, whether to use the new format, defaults to ``False`` :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] or list[aiosu.models.lazer.LazerScore] """ @@ -1011,6 +1028,7 @@ async def get_user_pinned( Optional, whether to use the new format, defaults to ``False`` :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] or list[aiosu.models.lazer.LazerScore] """ @@ -1039,6 +1057,7 @@ async def get_user_beatmap_scores( Optional, gamemode to search for :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] """ @@ -1073,6 +1092,7 @@ async def get_user_beatmaps( Optional, offset of the first beatmap to get :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested beatmaps :rtype: list[aiosu.models.beatmap.Beatmap] """ @@ -1105,6 +1125,7 @@ async def get_user_most_played( Optional, offset of the first beatmap to get :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of user playcount objects :rtype: list[aiosu.models.beatmap.BeatmapUserPlaycount] """ @@ -1137,6 +1158,7 @@ async def get_user_recent_activity( Optional, offset of the first event to get :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of events :rtype: list[aiosu.models.event.Event] """ @@ -1154,6 +1176,7 @@ async def get_events(self) -> EventResponse: r"""Get global events. :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Event response object :rtype: aiosu.models.event.EventResponse """ @@ -1183,6 +1206,7 @@ async def get_beatmap_scores(self, beatmap_id: int, **kwargs: Any) -> list[Score Optional, beatmap score ranking type :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of requested scores :rtype: list[aiosu.models.score.Score] """ @@ -1209,6 +1233,7 @@ async def get_beatmap(self, beatmap_id: int) -> Beatmap: :param beatmap_id: The ID of the beatmap :type beatmap_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmap data object :rtype: aiosu.models.beatmap.Beatmap """ @@ -1225,6 +1250,7 @@ async def get_beatmaps(self, beatmap_ids: list[int]) -> list[Beatmap]: :param beatmap_ids: The IDs of the beatmaps :type beatmap_ids: list[int] :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of beatmap data objects :rtype: list[aiosu.models.beatmap.Beatmap] """ @@ -1254,6 +1280,7 @@ async def lookup_beatmap(self, **kwargs: Any) -> Beatmap: :raises ValueError: If no arguments are specified :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmap data object :rtype: aiosu.models.beatmap.Beatmap """ @@ -1289,6 +1316,7 @@ async def get_beatmap_attributes( Optional, mods to apply to the result :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Difficulty attributes for a beatmap :rtype: aiosu.models.beatmap.BeatmapDifficultyAttributes """ @@ -1314,6 +1342,7 @@ async def get_beatmapset(self, beatmapset_id: int) -> Beatmapset: :param beatmapset_id: The ID of the beatmapset :type beatmapset_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset data object :rtype: aiosu.models.beatmap.Beatmapset """ @@ -1331,6 +1360,7 @@ async def lookup_beatmapset(self, beatmap_id: int) -> Beatmapset: :type beatmap_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset data object :rtype: aiosu.models.beatmap.Beatmapset """ @@ -1390,6 +1420,7 @@ async def search_beatmapsets( Optional, cursor string to get the next page of results :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset search response :rtype: list[aiosu.models.beatmap.BeatmapsetSearchResponse] """ @@ -1460,6 +1491,7 @@ async def get_beatmap_packs(self, **kwargs: Any) -> BeatmapPacksResponse: Optional, cursor string to get the next page of results :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmap packs response :rtype: aiosu.models.beatmap.BeatmapPacksResponse """ @@ -1489,6 +1521,7 @@ async def get_beatmap_pack(self, pack_tag: str) -> BeatmapPack: :type pack_tag: str :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmap pack object :rtype: aiosu.models.beatmap.BeatmapPack """ @@ -1522,6 +1555,7 @@ async def get_beatmapset_events(self, **kwargs: Any) -> list[BeatmapsetEvent]: Optional, event types :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of beatmapset events :rtype: list[aiosu.models.event.Event] """ @@ -1574,6 +1608,7 @@ async def get_beatmapset_discussions( Optional, cursor string :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset discussion response :rtype: aiosu.models.beatmap.BeatmapsetDiscussionResponse """ @@ -1628,6 +1663,7 @@ async def get_beatmapset_discussion_posts( Optional, cursor string :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset discussion post response :rtype: aiosu.models.beatmap.BeatmapsetDiscussionPostResponse """ @@ -1681,6 +1717,7 @@ async def get_beatmapset_discussion_votes( Optional, cursor string :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Beatmapset discussion vote response :rtype: aiosu.models.beatmap.BeatmapsetDiscussionVoteResponse """ @@ -1718,6 +1755,7 @@ async def get_score( :type mode: aiosu.models.gamemode.Gamemode :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Score data object :rtype: aiosu.models.score.Score """ @@ -1742,6 +1780,7 @@ async def get_score_replay( :type mode: aiosu.models.gamemode.Gamemode :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Replay file :rtype: io.BytesIO """ @@ -1779,6 +1818,7 @@ async def get_rankings( Optional, cursor string :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Rankings :rtype: aiosu.models.rankings.Rankings """ @@ -1810,6 +1850,7 @@ async def get_rankings_kudosu(self, **kwargs: Any) -> Rankings: Optional, page ID :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Rankings :rtype: aiosu.models.rankings.Rankings """ @@ -1829,6 +1870,7 @@ async def get_spotlights(self) -> list[Spotlight]: r"""Gets the current spotlights. :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of spotlights :rtype: list[aiosu.models.spotlight.Spotlight] """ @@ -1860,6 +1902,7 @@ async def get_forum_topic(self, topic_id: int, **kwargs: Any) -> ForumTopicRespo Optional, the cursor string to use for pagination. :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Forum topic response object :rtype: aiosu.models.forum.ForumTopicResponse """ @@ -1919,6 +1962,7 @@ async def create_forum_topic( Optional, the maximum number of votes a user can make. Defaults to 1 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Forum create topic response object :rtype: aiosu.models.forum.ForumCreateTopicResponse """ @@ -1959,6 +2003,7 @@ async def reply_forum_topic(self, topic_id: int, content: str) -> ForumPost: :param content: The content of the post :type content: str :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Forum post object :rtype: aiosu.models.forum.ForumPost """ @@ -1980,6 +2025,7 @@ async def edit_forum_topic_title(self, topic_id: int, new_title: str) -> ForumTo :param new_title: The new title of the topic :type new_title: str :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Forum topic object :rtype: aiosu.models.forum.ForumTopic """ @@ -2003,6 +2049,7 @@ async def edit_forum_post(self, post_id: int, new_content: str) -> ForumPost: :param new_content: The new content of the post :type new_content: str :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Forum post object :rtype: aiosu.models.forum.ForumPost """ @@ -2030,6 +2077,7 @@ async def get_chat_ack(self, **kwargs: Any) -> list[ChatUserSilence]: Optional, the last silence ID received :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of chat user silence objects :rtype: list[aiosu.models.chat.ChatUserSilence] """ @@ -2064,6 +2112,7 @@ async def get_chat_updates(self, since: int, **kwargs: Any) -> ChatUpdateRespons :raises ValueError: If limit is not between 1 and 50 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat update response object :rtype: aiosu.models.chat.ChatUpdateResponse """ @@ -2090,6 +2139,7 @@ async def get_channel(self, channel_id: int) -> ChatChannelResponse: :param channel_id: The channel ID to get :type channel_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat channel object :rtype: aiosu.models.chat.ChatChannelResponse """ @@ -2105,6 +2155,7 @@ async def get_channels(self) -> list[ChatChannel]: r"""Gets a list of joinable public channels. :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of chat channel objects :rtype: list[aiosu.models.chat.ChatChannel] """ @@ -2138,6 +2189,7 @@ async def get_channel_messages( :raises ValueError: If limit is not between 1 and 50 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of chat message objects :rtype: list[aiosu.models.chat.ChatMessage] """ @@ -2182,6 +2234,7 @@ async def create_chat_channel( :raises ValueError: If missing required parameters :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat channel object :rtype: aiosu.models.chat.ChatChannel """ @@ -2218,6 +2271,7 @@ async def join_channel(self, channel_id: int, user_id: int) -> ChatChannel: :param user_id: The user ID to join as :type user_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat channel object :rtype: aiosu.models.chat.ChatChannel """ @@ -2237,6 +2291,7 @@ async def leave_channel(self, channel_id: int, user_id: int) -> None: :param user_id: The user ID to leave as :type user_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired """ url = f"{self.base_url}/api/v2/chat/channels/{channel_id}/users/{user_id}" await self._request("DELETE", url) @@ -2253,6 +2308,7 @@ async def mark_read(self, channel_id: int, message_id: int) -> None: :param message_id: The message ID to mark as read up to :type message_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired """ url = f"{self.base_url}/api/v2/chat/channels/{channel_id}/mark-as-read/{message_id}" await self._request("PUT", url) @@ -2276,6 +2332,7 @@ async def send_message( :param is_action: Whether the message is an action :type is_action: bool :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat message object :rtype: aiosu.models.chat.ChatMessage """ @@ -2314,6 +2371,7 @@ async def send_private_message( Optional, client-side message identifier to be sent back in response and websocket json :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Chat message create response object :rtype: aiosu.models.chat.ChatMessageCreateResponse """ @@ -2349,6 +2407,7 @@ async def get_multiplayer_matches( :raises ValueError: If limit is not between 1 and 50 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Multiplayer matches response object :rtype: aiosu.models.multiplayer.MultiplayerMatchesResponse """ @@ -2391,6 +2450,7 @@ async def get_multiplayer_match( :raises ValueError: If limit is not between 1 and 100 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Multiplayer match response object :rtype: aiosu.models.multiplayer.MultiplayerMatchResponse """ @@ -2429,6 +2489,7 @@ async def get_multiplayer_rooms(self, **kwargs: Any) -> list[MultiplayerRoom]: :raises ValueError: If limit is not between 1 and 50 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: List of multiplayer rooms :rtype: list[aiosu.models.multiplayer.MultiplayerRoom] """ @@ -2457,6 +2518,7 @@ async def get_multiplayer_room(self, room_id: int) -> MultiplayerRoom: :type room_id: int :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Multiplayer room object :rtype: aiosu.models.multiplayer.MultiplayerRoom """ @@ -2486,6 +2548,7 @@ async def get_multiplayer_leaderboard( :raises ValueError: If limit is not between 1 and 50 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Multiplayer leaderboard response object :rtype: aiosu.models.multiplayer.MultiplayerLeaderboardResponse """ @@ -2526,6 +2589,7 @@ async def get_multiplayer_scores( :raises ValueError: If limit is not between 1 and 100 :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired :return: Multiplayer scores response object :rtype: aiosu.models.multiplayer.MultiplayerScoresResponse """ @@ -2555,14 +2619,23 @@ async def revoke_token(self) -> None: r"""Revokes the current token and closes the session. :raises APIException: Contains status code and error message + :raises RefreshTokenExpiredError: If the client refresh token has expired """ url = f"{self.base_url}/api/v2/oauth/tokens/current" await self._request("DELETE", url) await self._delete_token() - await self.close() + await self.aclose() - async def close(self) -> None: + async def aclose(self) -> None: """Closes the client session.""" if self._session: await self._session.close() self._session = None + + async def close(self) -> None: + """Closes the client session. (Deprecated)""" + warn( + "close is deprecated, use aclose instead. Will be removed on 2024-03-01", + DeprecationWarning, + ) + await self.aclose() diff --git a/aiosu/v2/clientstorage.py b/aiosu/v2/clientstorage.py index 8bf54ca..3e285c2 100644 --- a/aiosu/v2/clientstorage.py +++ b/aiosu/v2/clientstorage.py @@ -9,6 +9,7 @@ from typing import cast from typing import TYPE_CHECKING from typing import TypeVar +from warnings import warn from . import Client from ..events import ClientAddEvent @@ -79,7 +80,7 @@ async def __aexit__( exc: Optional[BaseException], traceback: Optional[TracebackType], ) -> None: - await self.close() + await self.aclose() def on_client_add(self, func: F) -> F: """ @@ -232,7 +233,15 @@ async def revoke_client(self, client_uid: int) -> None: "No client exists with the given ID.", ) - async def close(self) -> None: + async def aclose(self) -> None: r"""Closes all client sessions.""" for client in self.clients.values(): - await client.close() + await client.aclose() + + async def close(self) -> None: + """Closes the client session. (Deprecated)""" + warn( + "close is deprecated, use aclose instead. Will be removed on 2024-03-01", + DeprecationWarning, + ) + await self.aclose() diff --git a/docs/source/index.rst b/docs/source/index.rst index 3bf83d3..293eed6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -36,6 +36,8 @@ If you need assistance, you should look here: Breaking changes ---------------- +**v2.2.0:** The `close()` methods of the clients are now named `aclose()` as per naming conventions for asynchronous methods. The old method is still available with a deprecation warning, but will be removed on 2024-03-01. + **v2.0.3:** The replay model has been moved to `models/files/replay.py` and the `Replay` class has been renamed to `ReplayFile`. **v2.0.0:** The library now uses *Pydantic v2*. This means that the following changes have occured: diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index b95d1b2..04b1975 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -49,7 +49,7 @@ API v1 Example # regular syntax client = aiosu.v1.Client("osu api token") user = await client.get_user(7782553) - await client.close() + await client.aclose() if __name__ == "__main__": @@ -85,7 +85,7 @@ API v2 Example # regular syntax client = aiosu.v2.Client(client_secret="secret", client_id=1000, token=token) user = await client.get_me() - await client.close() + await client.aclose() if __name__ == "__main__": diff --git a/examples/v1/client.py b/examples/v1/client.py index 3a586ab..20cddc6 100644 --- a/examples/v1/client.py +++ b/examples/v1/client.py @@ -13,7 +13,7 @@ async def main(): # regular syntax client = aiosu.v1.Client("osu api token") user = await client.get_user(7782553) - await client.close() + await client.aclose() if __name__ == "__main__": diff --git a/examples/v2/client.py b/examples/v2/client.py index 60dd282..9c718f8 100644 --- a/examples/v2/client.py +++ b/examples/v2/client.py @@ -25,7 +25,7 @@ async def main(): # regular syntax client = aiosu.v2.Client(client_secret="secret", client_id=1000, token=token) user = await client.get_me() - await client.close() + await client.aclose() # client credentials example app_client = aiosu.v2.Client( diff --git a/examples/v2/clientstorage.py b/examples/v2/clientstorage.py index 967f08c..255faca 100644 --- a/examples/v2/clientstorage.py +++ b/examples/v2/clientstorage.py @@ -25,7 +25,7 @@ async def main(): cs = aiosu.v2.ClientStorage(client_secret="secret", client_id=1000) client = await cs.add_client(token=token) user = await client.get_me() - await cs.close() + await cs.aclose() # client credentials example app_client = await cs.app_client diff --git a/examples/v2/cursor.py b/examples/v2/cursor.py index 92d30e9..42c2122 100644 --- a/examples/v2/cursor.py +++ b/examples/v2/cursor.py @@ -12,7 +12,7 @@ async def main(): discussions_next = await discussions.next() - await client.close() + await client.aclose() if __name__ == "__main__": diff --git a/examples/v2/custom_repository.py b/examples/v2/custom_repository.py index 9afef13..a65423b 100644 --- a/examples/v2/custom_repository.py +++ b/examples/v2/custom_repository.py @@ -92,7 +92,7 @@ async def main(): ) client = await cs.add_client(token=token) user = await client.get_me() - await cs.close() + await cs.aclose() # note: you can also use a custom repo on a client by passing repository and session_id. if the repo does not contain the token, it will be added from the token passed to the client. # client = aiosu.v2.Client( diff --git a/tests/generate/main.py b/tests/generate/main.py index ba9b29d..6ed0056 100644 --- a/tests/generate/main.py +++ b/tests/generate/main.py @@ -168,7 +168,7 @@ def _register_routes(self) -> None: async def run(self) -> None: self.client._session = aiohttp.ClientSession() await super().run() - await self.client.close() + await self.client.aclose() class TestGeneratorV2(TestGeneratorBase): @@ -733,7 +733,7 @@ async def run(self) -> None: params={"ruleset_id": score["mode_int"]}, ) - await self.client.close() + await self.client.aclose() async def main() -> None: diff --git a/tests/test_v2/test_clientstorage.py b/tests/test_v2/test_clientstorage.py index 1e99ebb..9a039e5 100644 --- a/tests/test_v2/test_clientstorage.py +++ b/tests/test_v2/test_clientstorage.py @@ -34,7 +34,7 @@ async def test_get_client(self, mocker, token, user): client_2 = await client_storage.get_client(id=client_1.session_id) assert client_1 == client_2 - await client_storage.close() + await client_storage.aclose() @pytest.mark.asyncio async def test_add_client(self, mocker, token, user): @@ -46,7 +46,7 @@ async def test_add_client(self, mocker, token, user): client_2 = await client_storage.get_client(id=client_1.session_id) assert client_1 == client_2 - await client_storage.close() + await client_storage.aclose() @pytest.mark.asyncio async def test_revoke_client(self, mocker, token, user): @@ -67,4 +67,4 @@ def mock_request(*args, **kwargs): with pytest.raises(aiosu.exceptions.InvalidClientRequestedError): await client_storage.get_client(id=client.session_id) - await client_storage.close() + await client_storage.aclose() diff --git a/tests/test_v2/test_events.py b/tests/test_v2/test_events.py index 7d2d369..9fd2b9d 100644 --- a/tests/test_v2/test_events.py +++ b/tests/test_v2/test_events.py @@ -56,7 +56,7 @@ async def decorated(event): await client_storage.add_client(token=token) assert decorated.times_called == 1 - await client_storage.close() + await client_storage.aclose() @pytest.mark.asyncio async def test_cs_update_client(self, mocker, token, token_expired, user): @@ -78,7 +78,7 @@ async def decorated(event): user = await client.get_me() assert decorated.times_called == 1 - await client_storage.close() + await client_storage.aclose() @pytest.mark.asyncio async def test_update_client(self, mocker, token, token_expired, user): @@ -100,4 +100,4 @@ async def decorated(event): user = await client.get_me() assert decorated.times_called == 1 - await client.close() + await client.aclose()