From 5bcb5a6bd2fc7711e69977368229c7ab01ed25ad Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:26:07 +0300 Subject: [PATCH 01/13] tune logging a bit switch message "Returning new tokens message..." level from info to debug level removed logger.critical, as there is a decorator for exception switch rps cooldown message level from warning to info --- shikithon/api.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index d92b6e01..ec0d6920 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -422,10 +422,9 @@ def _get_access_token(self, refresh_token: bool = False) -> Tuple[str, str]: request_type=RequestType.POST) try: - logger.info('Returning new access and refresh tokens') + logger.debug('Returning new access and refresh tokens') return oauth_json['access_token'], oauth_json['refresh_token'] except KeyError as err: - logger.critical('Failed returning new tokens') error_info = dumps(oauth_json) raise AccessTokenException( 'An error occurred while receiving tokens, ' @@ -527,7 +526,7 @@ def _request( return response if response.status_code == ResponseCode.RETRY_LATER.value: - logger.warning('Hit RPS cooldown. Waiting on request repeat') + logger.info('Hit RPS cooldown. Waiting on request repeat') sleep(RATE_LIMIT_RPS_COOLDOWN) return self._request(url, data, headers, query, request_type) From 3e41470e05d5bee21e255b2b5620bc98523641fe Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:26:49 +0300 Subject: [PATCH 02/13] update models add Dialog model fix docstring of message.py --- shikithon/models/dialog.py | 11 +++++++++++ shikithon/models/message.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 shikithon/models/dialog.py diff --git a/shikithon/models/dialog.py b/shikithon/models/dialog.py new file mode 100644 index 00000000..ba42b175 --- /dev/null +++ b/shikithon/models/dialog.py @@ -0,0 +1,11 @@ +"""Model for api/dialogs""" +from pydantic import BaseModel + +from shikithon.models.message import Message +from shikithon.models.user import User + + +class Dialog(BaseModel): + """Represents dialog entity.""" + target_user: User + message: Message diff --git a/shikithon/models/message.py b/shikithon/models/message.py index 608babb4..e2c2b2fb 100644 --- a/shikithon/models/message.py +++ b/shikithon/models/message.py @@ -1,4 +1,4 @@ -"""Model for /api/messages""" +"""Model for /api/messages and submodel for dialog.py""" from datetime import datetime from typing import Optional From d21841577c14498e3cd3a57cdace1646a1778874 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:31:50 +0300 Subject: [PATCH 03/13] remove "false" error messages in response and return None note: this error message was added by mistake in all paginated methods, where response can return empty list --- shikithon/api.py | 40 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index ec0d6920..18604687 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -680,9 +680,7 @@ def animes(self, search=search)) if response: return [Anime(**anime) for anime in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def anime(self, anime_id: int) -> Anime: """ @@ -833,9 +831,7 @@ def anime_topics( episode=episode)) if response: return [Topic(**topic) for topic in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None @protected_method() def appears(self, comment_ids: List[str]) -> bool: @@ -883,9 +879,7 @@ def bans(self, query=Utils.generate_query_dict(page=page, limit=limit)) if response: return [Ban(**ban) for ban in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def calendar( self, @@ -969,9 +963,7 @@ def clubs(self, search=search)) if response: return [Club(**club) for club in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def club(self, club_id: int) -> Club: """ @@ -1283,9 +1275,7 @@ def comments(self, desc=desc)) if response: return [Comment(**comment) for comment in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def comment(self, comment_id: int) -> Comment: """ @@ -1502,9 +1492,7 @@ def users(self, query=Utils.generate_query_dict(page=page, limit=limit)) if response: return [User(**user) for user in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def user(self, user_id: Union[str, int], @@ -1661,9 +1649,7 @@ def user_anime_rates( censored=censored)) if response: return [UserList(**user_list) for user_list in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def user_manga_rates( self, @@ -1708,9 +1694,7 @@ def user_manga_rates( censored=censored)) if response: return [UserList(**user_list) for user_list in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def user_favourites(self, user_id: Union[int, str], @@ -1778,9 +1762,7 @@ def current_user_messages( type=message_type)) if response: return [Message(**message) for message in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None @protected_method(scope='messages') def current_user_unread_messages( @@ -1854,9 +1836,7 @@ def user_history( target_type=target_type)) if response: return [History(**history) for history in response] - logger.info('An error occurred when executing API method') - logger.debug(f'Information about an error: {response=}') - return response + return None def user_bans(self, user_id: Union[int, str], From c9fed746a819d465c0066d199333d1c2801d7423 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:37:40 +0300 Subject: [PATCH 04/13] update API's request method response is no longer None by default change if request_type chain to return None if unknown type was provided remove check for response is None switch message about failed JSON extracting level from error to warning --- shikithon/api.py | 54 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index 18604687..9786363a 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -493,37 +493,37 @@ def _request( :return: Response JSON, text or status code :rtype: Union[List[Dict[str, Any]], Dict[str, Any], str, None] """ - response: Union[Response, None] = None logger.info(f'{request_type.value} {url}') logger.debug(f'Request info details: {data=}, {headers=}, {query=}') if request_type == RequestType.GET: - response = self._session.get(url, headers=headers, params=query) - if request_type == RequestType.POST: - response = self._session.post(url, - headers=headers, - params=query, - json=data) - if request_type == RequestType.PUT: - response = self._session.put(url, - headers=headers, - params=query, - json=data) - if request_type == RequestType.PATCH: - response = self._session.patch(url, - headers=headers, - params=query, - json=data) - if request_type == RequestType.DELETE: - response = self._session.delete(url, - headers=headers, - params=query, - json=data) - - if response is None: - logger.debug('Response is empty. Returning None') - return response + response: Response = self._session.get(url, + headers=headers, + params=query) + elif request_type == RequestType.POST: + response: Response = self._session.post(url, + headers=headers, + params=query, + json=data) + elif request_type == RequestType.PUT: + response: Response = self._session.put(url, + headers=headers, + params=query, + json=data) + elif request_type == RequestType.PATCH: + response: Response = self._session.patch(url, + headers=headers, + params=query, + json=data) + elif request_type == RequestType.DELETE: + response: Response = self._session.delete(url, + headers=headers, + params=query, + json=data) + else: + logger.debug('Unknown request_type. Returning None') + return None if response.status_code == ResponseCode.RETRY_LATER.value: logger.info('Hit RPS cooldown. Waiting on request repeat') @@ -534,7 +534,7 @@ def _request( logger.debug('Extracting JSON from response') return response.json() except JSONDecodeError: - logger.error('Failed JSON extracting. Returning text/status_code') + logger.warning('Failed JSON extracting. Returning text/status_code') return response.status_code if not response.text else response.text def refresh_tokens(self): From 7d5cd22fe117f830d5530bfa3e265f787c51b851 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:38:19 +0300 Subject: [PATCH 05/13] update docstring return info for all paginated methods --- shikithon/api.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index 9786363a..bd9b9e5b 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -648,7 +648,7 @@ def animes(self, :param search: Search phrase to filter animes by name :type search: Union[str, None] - :return: Animes list + :return: Animes list or None, if page is empty :rtype: Union[List[Anime], None] """ logger.debug('Executing API method') @@ -814,7 +814,7 @@ def anime_topics( :param episode: Number of anime episode :type episode: Union[int, None] - :return: List of topics + :return: List of topics or None, if page is empty :rtype: Union[List[Topic], None] """ logger.debug('Executing API method') @@ -865,7 +865,7 @@ def bans(self, :param limit: Number of results limit :type limit: Union[int, None] - :return: List of recent bans + :return: List of recent bans or None, if page is empty :rtype: Union[List[Ban], None] """ logger.debug('Executing API method') @@ -947,7 +947,7 @@ def clubs(self, :param search: Search phrase to filter clubs by name :type search: Union[str, None] - :return: Clubs list + :return: Clubs list or None, if page is empty :rtype: Union[List[Club], None] """ logger.debug('Executing API method') @@ -1257,7 +1257,7 @@ def comments(self, :param desc: Status of description in request. Can be 1 or 0 :type desc: Union[int, None] = None - :return: List of comments + :return: List of comments or None, if page is empty :rtype: Union[List[Comment], None] """ logger.debug('Executing API method') @@ -1631,7 +1631,7 @@ def user_anime_rates( :param censored: Type of anime censorship :type censored: Union[Censorship, None] - :return: User's anime list + :return: User's anime list or None, if page is empty :rtype: Union[List[UserList], None] """ logger.debug('Executing API method') @@ -1677,7 +1677,7 @@ def user_manga_rates( :param censored: Type of manga censorship :type censored: Union[Censorship, None] - :return: User's manga list + :return: User's manga list or None, if page is empty :rtype: Union[List[UserList], None] """ logger.debug('Executing API method') @@ -1744,7 +1744,7 @@ def current_user_messages( :param message_type: Type of message :type message_type: MessageType - :return: Current user's messages + :return: Current user's messages or None, if page is empty :rtype: Union[List[Message], None] """ logger.debug('Executing API method') @@ -1818,7 +1818,7 @@ def user_history( :param target_type: Type of target (Anime/Manga) :type target_type: Union[TargetType, None] - :return: User's history + :return: User's history or None, if page is empty :rtype: Union[List[History], None] """ logger.debug('Executing API method') From f82deb3b604208233ff018181d98f166dd06d5be Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:42:00 +0300 Subject: [PATCH 06/13] fix typing for response in paginated methods --- shikithon/api.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index bd9b9e5b..bfd79dbe 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -659,7 +659,7 @@ def animes(self, logger.debug('Checking score parameter') score = Utils.validate_query_number(score, 9) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.animes, query=Utils.generate_query_dict(page=page, limit=limit, @@ -823,7 +823,7 @@ def anime_topics( logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 30) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.anime_topics(anime_id), query=Utils.generate_query_dict(page=page, limit=limit, @@ -874,7 +874,7 @@ def bans(self, logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 30) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.bans_list, query=Utils.generate_query_dict(page=page, limit=limit)) if response: @@ -956,7 +956,7 @@ def clubs(self, logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 30) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.clubs, query=Utils.generate_query_dict(page=page, limit=limit, @@ -1266,7 +1266,7 @@ def comments(self, logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 30) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.comments, query=Utils.generate_query_dict(page=page, limit=limit, @@ -1487,7 +1487,7 @@ def users(self, logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 100) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.users, query=Utils.generate_query_dict(page=page, limit=limit)) if response: @@ -1640,7 +1640,7 @@ def user_anime_rates( logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 5000) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.user_anime_rates(user_id), query=Utils.generate_query_dict(is_nickname=is_nickname, page=page, @@ -1686,7 +1686,7 @@ def user_manga_rates( logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 5000) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.user_manga_rates(user_id), query=Utils.generate_query_dict(is_nickname=is_nickname, page=page, @@ -1753,7 +1753,7 @@ def current_user_messages( logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 100) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.user_messages(user_id), headers=self._authorization_header, query=Utils.generate_query_dict(is_nickname=is_nickname, @@ -1827,7 +1827,7 @@ def user_history( logger.debug('Checking limit parameter') limit = Utils.validate_query_number(limit, 100) - response: Union[List[Dict[str, Any]], None] = self._request( + response: List[Dict[str, Any]] = self._request( self._endpoints.user_history(user_id), query=Utils.generate_query_dict(is_nickname=is_nickname, page=page, From 02735f0f10fe692aa9dd9c871005637f2819cb23 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 12:52:04 +0300 Subject: [PATCH 07/13] fix dialog endpoint parameter and docstring --- shikithon/endpoints.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shikithon/endpoints.py b/shikithon/endpoints.py index ee48fd37..707c41c0 100644 --- a/shikithon/endpoints.py +++ b/shikithon/endpoints.py @@ -609,12 +609,12 @@ def dialogs(self) -> str: """ return f'{self.base_url}/dialogs' - def dialog(self, dialog_id: int) -> str: + def dialog(self, dialog_id: Union[int, str]) -> str: """ - Returns endpoint of a certain comment. + Returns endpoint of a certain dialog with user. - :param dialog_id: Dialog ID for endpoint - :type dialog_id: int + :param dialog_id: User ID/Nickname for endpoint + :type dialog_id: Union[int, str] :return: Dialog endpoint link :rtype: str From b146282f07bcfce05252d52930c43eb99b265bbd Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:26:58 +0300 Subject: [PATCH 08/13] add /api/dialogs methods --- shikithon/api.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/shikithon/api.py b/shikithon/api.py index bfd79dbe..c1401370 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -40,6 +40,7 @@ MangaConstants, SmileyConstants, UserRateConstants) from shikithon.models.creator import Creator +from shikithon.models.dialog import Dialog from shikithon.models.favourites import Favourites from shikithon.models.franchise_tree import FranchiseTree from shikithon.models.history import History @@ -1466,6 +1467,59 @@ def smileys_constants(self) -> List[SmileyConstants]: self._endpoints.smileys_constants) return [SmileyConstants(**smiley) for smiley in response] + @protected_method(scope='messages') + def dialogs(self) -> Union[List[Dialog], None]: + """ + Returns list of current user's dialogs. + + :return: List of dialogs or None, if there are no dialogs + :rtype: Union[List[Dialog], None] + """ + logger.debug('Executing API method') + response: List[Dict[str, Any]] = self._request( + self._endpoints.dialogs, headers=self._authorization_header) + if response: + return [Dialog(**dialog) for dialog in response] + return None + + @protected_method(scope='messages') + def dialog(self, user_id: Union[int, str]) -> Union[List[Message], None]: + """ + Returns list of current user's messages with certain user. + + :param user_id: ID/Nickname of the user to get dialog + :type user_id: Union[int, str] + + :return: List of messages or None, if there are no messages + :rtype: Union[List[Message], None] + """ + logger.debug('Executing API method') + response: List[Dict[str, Any]] = self._request( + self._endpoints.dialog(user_id), headers=self._authorization_header) + if response: + return [Message(**message) for message in response] + return None + + @protected_method(scope='messages') + def delete_dialog(self, user_id: Union[int, str]) -> bool: + """ + Deletes dialog of current user with certain user. + + :param user_id: ID/Nickname of the user to delete dialog + :type user_id: Union[int, str] + + :return: Status of message deletion + :rtype: bool + """ + logger.debug('Executing API method') + response: List[Dict[str, Any]] = self._request( + self._endpoints.dialog(user_id), + headers=self._authorization_header, + request_type=RequestType.DELETE) + logger.debug( + f'Detailed information about deleting the dialog: {response=}') + return 'notice' in response + def users(self, page: Union[int, None] = None, limit: Union[int, None] = None) -> Union[List[User], None]: From 677995cda42732404c7f61d836a826abdd14e5c1 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:29:10 +0300 Subject: [PATCH 09/13] update logging change level and message of logger on JSONDecodeError remove unrelevant info for some POST/PATCH/DELETE methods fix rtype of delete_comment method --- shikithon/api.py | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index c1401370..8938a184 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -535,7 +535,7 @@ def _request( logger.debug('Extracting JSON from response') return response.json() except JSONDecodeError: - logger.warning('Failed JSON extracting. Returning text/status_code') + logger.debug('Can\'t extract JSON. Returning status_code/text') return response.status_code if not response.text else response.text def refresh_tokens(self): @@ -1088,12 +1088,10 @@ def club_update( collection_ids=collection_ids, banned_user_ids=banned_user_ids), request_type=RequestType.PATCH) + logger.debug( + f'Detailed information about updating the club: {response=}') if 'errors' in response: - logger.info('There was an error when updating the club') - logger.debug( - f'There was an error when updating the club: {response=}') return False, response['errors'] - logger.info('Successfully updated the club') return True, Club(**response) def club_animes(self, club_id: int) -> List[Anime]: @@ -1202,12 +1200,10 @@ def club_join(self, club_id: int): int] = self._request(self._endpoints.club_join(club_id), headers=self._authorization_header, request_type=RequestType.POST) + logger.debug( + f'Detailed information about joining the club: {response=}') if isinstance(response, int) and response == ResponseCode.SUCCESS.value: - logger.info('Successfully joined the club') return True - logger.info('There was an error when joining the club ' - 'or are you already a member of it') - logger.debug(f'There was an error when joining the club: {response=}') return False @protected_method(scope='clubs') @@ -1226,12 +1222,10 @@ def club_leave(self, club_id: int) -> bool: self._endpoints.club_leave(club_id), headers=self._authorization_header, request_type=RequestType.POST) + logger.debug( + f'Detailed information about leaving the club: {response=}') if isinstance(response, int) and response == ResponseCode.SUCCESS.value: - logger.info('Successfully left the club') return True - logger.info('There was an error when leaving the club ' - 'or you are already not a member of it') - logger.debug(f'There was an error when leaving the club: {response=}') return False def comments(self, @@ -1345,13 +1339,10 @@ def create_comment( headers=self._authorization_header, data=data_dict, request_type=RequestType.POST) - + logger.debug( + f'Detailed information about creating the comment: {response=}') if 'errors' in response: - logger.info('An error occurred when creating a comment') - logger.debug('Information about an error ' - f'when creating a comment: {response=}') return False, response['errors'] - logger.info('New comment successfully created') return True, Comment(**response) @protected_method(scope='comments') @@ -1377,12 +1368,10 @@ def update_comment(self, comment_id: int, headers=self._authorization_header, data=Utils.generate_data_dict(dict_name='comment', body=body), request_type=RequestType.PATCH) + logger.debug( + f'Detailed information about updating the comment: {response=}') if 'errors' in response: - logger.info('An error occurred when updating a comment') - logger.debug('Information about an error ' - f'when updating a comment: {response=}') return False, response['errors'] - logger.info(f'Comment #{comment_id} successfully updated') return True, Comment(**response) @protected_method(scope='comments') @@ -1394,19 +1383,16 @@ def delete_comment(self, comment_id: int) -> bool: :type comment_id: int :return: Status of comment deletion + :rtype: bool """ logger.debug('Executing API method') response: Dict[str, Any] = self._request(self._endpoints.comment(comment_id), headers=self._authorization_header, request_type=RequestType.DELETE) - if 'notice' in response: - logger.info(f'Comment #{comment_id} successfully deleted') - return True - logger.info('An error occurred when deleting a comment') logger.debug( - f'Information about an error when deleting a comment: {response=}') - return False + f'Detailed information about deleting the comment: {response=}') + return 'notice' in response def anime_constants(self) -> AnimeConstants: """ From 103925ea6f41916bfad97f4efee4097ea3aed93a Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:41:07 +0300 Subject: [PATCH 10/13] updated some API methods now POST/PATCH requests returns only model with updated info or None club_join and club_leave methods check for response code simplified --- shikithon/api.py | 93 ++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index 8938a184..7352dedd 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -982,26 +982,26 @@ def club(self, club_id: int) -> Club: @protected_method(scope='clubs') def club_update( - self, - club_id: int, - name: Union[str, None] = None, - join_policy: Union[JoinPolicy, None] = None, - description: Union[str, None] = None, - display_images: Union[bool, None] = None, - comment_policy: Union[CommentPolicy, None] = None, - topic_policy: Union[TopicPolicy, None] = None, - page_policy: Union[PagePolicy, None] = None, - image_upload_policy: Union[ImageUploadPolicy, None] = None, - is_censored: Union[bool, None] = None, - anime_ids: Union[List[int], None] = None, - manga_ids: Union[List[int], None] = None, - ranobe_ids: Union[List[int], None] = None, - character_ids: Union[List[int], None] = None, - club_ids: Union[List[int], None] = None, - admin_ids: Union[List[int], None] = None, - collection_ids: Union[List[int], None] = None, - banned_user_ids: Union[List[int], None] = None - ) -> Tuple[bool, Union[Club, str]]: + self, + club_id: int, + name: Union[str, None] = None, + join_policy: Union[JoinPolicy, None] = None, + description: Union[str, None] = None, + display_images: Union[bool, None] = None, + comment_policy: Union[CommentPolicy, None] = None, + topic_policy: Union[TopicPolicy, None] = None, + page_policy: Union[PagePolicy, None] = None, + image_upload_policy: Union[ImageUploadPolicy, None] = None, + is_censored: Union[bool, None] = None, + anime_ids: Union[List[int], None] = None, + manga_ids: Union[List[int], None] = None, + ranobe_ids: Union[List[int], None] = None, + character_ids: Union[List[int], None] = None, + club_ids: Union[List[int], None] = None, + admin_ids: Union[List[int], None] = None, + collection_ids: Union[List[int], None] = None, + banned_user_ids: Union[List[int], + None] = None) -> Union[Club, None]: """ Update info/settings about/of club. @@ -1059,10 +1059,8 @@ def club_update( :param banned_user_ids: New banned user ids of club :type banned_user_ids: Union[List[int], None] - :return: Tuple of update status and response. - On successful update, returns True and Club model, - otherwise, False and error message - :rtype: Tuple[bool, Union[Club, str]] + :return: Updated club info or None if an error occurred + :rtype: Union[Club, None] """ logger.debug('Executing API method') response: Dict[str, Any] = self._request( @@ -1090,9 +1088,7 @@ def club_update( request_type=RequestType.PATCH) logger.debug( f'Detailed information about updating the club: {response=}') - if 'errors' in response: - return False, response['errors'] - return True, Club(**response) + return Club(**response) if 'errors' not in response else None def club_animes(self, club_id: int) -> List[Anime]: """ @@ -1202,9 +1198,7 @@ def club_join(self, club_id: int): request_type=RequestType.POST) logger.debug( f'Detailed information about joining the club: {response=}') - if isinstance(response, int) and response == ResponseCode.SUCCESS.value: - return True - return False + return response == ResponseCode.SUCCESS.value @protected_method(scope='clubs') def club_leave(self, club_id: int) -> bool: @@ -1224,9 +1218,7 @@ def club_leave(self, club_id: int) -> bool: request_type=RequestType.POST) logger.debug( f'Detailed information about leaving the club: {response=}') - if isinstance(response, int) and response == ResponseCode.SUCCESS.value: - return True - return False + return response == ResponseCode.SUCCESS.value def comments(self, commentable_id: int, @@ -1289,13 +1281,12 @@ def comment(self, comment_id: int) -> Comment: @protected_method(scope='comments') def create_comment( - self, - body: str, - commentable_id: int, - commentable_type: CommentableType, - is_offtopic: Union[bool, None] = None, - broadcast: Union[bool, - None] = None) -> Tuple[bool, Union[Comment, str]]: + self, + body: str, + commentable_id: int, + commentable_type: CommentableType, + is_offtopic: Union[bool, None] = None, + broadcast: Union[bool, None] = None) -> Union[Comment, None]: """ Creates comment. @@ -1317,10 +1308,8 @@ def create_comment( :param broadcast: Broadcast comment in club’s topic status :type broadcast: Union[bool, None] - :return: Tuple of update status and response. - On successful update, returns True and Comment model, - otherwise, False and error message - :rtype: Tuple[bool, Union[Comment, str]] + :return: Updated comment info or None if an error occurred + :rtype: Union[Comment, None] """ logger.debug('Executing API method') data_dict: Dict[str, Any] = Utils.generate_data_dict( @@ -1341,13 +1330,11 @@ def create_comment( request_type=RequestType.POST) logger.debug( f'Detailed information about creating the comment: {response=}') - if 'errors' in response: - return False, response['errors'] - return True, Comment(**response) + return Comment(**response) if 'errors' not in response else None @protected_method(scope='comments') def update_comment(self, comment_id: int, - body: str) -> Tuple[bool, Union[Comment, str]]: + body: str) -> Union[Comment, None]: """ Updates comment. @@ -1357,10 +1344,8 @@ def update_comment(self, comment_id: int, :param body: New body of comment :type body: str - :return: Tuple of update status and response. - On successful update, returns True and Comment model, - otherwise, False and error message - :rtype: Tuple[bool, Union[Comment, str]] + :return: Updated comment info or None if an error occurred + :rtype: Union[Comment, None] """ logger.debug('Executing API method') response: Dict[str, Any] = self._request( @@ -1370,9 +1355,7 @@ def update_comment(self, comment_id: int, request_type=RequestType.PATCH) logger.debug( f'Detailed information about updating the comment: {response=}') - if 'errors' in response: - return False, response['errors'] - return True, Comment(**response) + return Comment(**response) if 'errors' not in response else None @protected_method(scope='comments') def delete_comment(self, comment_id: int) -> bool: From fae414a2d674eea6729eeb176abeb44af6ee53ed Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:47:45 +0300 Subject: [PATCH 11/13] fix pylint hook name --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e8bc3592..ba96f0d3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,7 +25,7 @@ repos: exclude: doc/data/messages/(r/reimported|w/wrong-import-order|u/ungrouped-imports|m/misplaced-future)/bad.py types: [python] - id: pylint - name: Checking docs with pylint + name: Checking code with pylint language: python entry: pylint args: ["-rn", "-sn", "--rcfile=.pylintrc", "--load-plugins=pylint.extensions.docparams"] From 49d858b77aa7ed5d510c7c1232fcab9b2bbe5da6 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:50:11 +0300 Subject: [PATCH 12/13] remove colon in detailed info message --- shikithon/api.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/shikithon/api.py b/shikithon/api.py index 7352dedd..efb4a4fd 100644 --- a/shikithon/api.py +++ b/shikithon/api.py @@ -1087,7 +1087,7 @@ def club_update( banned_user_ids=banned_user_ids), request_type=RequestType.PATCH) logger.debug( - f'Detailed information about updating the club: {response=}') + f'Detailed information about updating the club {response=}') return Club(**response) if 'errors' not in response else None def club_animes(self, club_id: int) -> List[Anime]: @@ -1196,8 +1196,7 @@ def club_join(self, club_id: int): int] = self._request(self._endpoints.club_join(club_id), headers=self._authorization_header, request_type=RequestType.POST) - logger.debug( - f'Detailed information about joining the club: {response=}') + logger.debug(f'Detailed information about joining the club {response=}') return response == ResponseCode.SUCCESS.value @protected_method(scope='clubs') @@ -1216,8 +1215,7 @@ def club_leave(self, club_id: int) -> bool: self._endpoints.club_leave(club_id), headers=self._authorization_header, request_type=RequestType.POST) - logger.debug( - f'Detailed information about leaving the club: {response=}') + logger.debug(f'Detailed information about leaving the club {response=}') return response == ResponseCode.SUCCESS.value def comments(self, @@ -1329,7 +1327,7 @@ def create_comment( data=data_dict, request_type=RequestType.POST) logger.debug( - f'Detailed information about creating the comment: {response=}') + f'Detailed information about creating the comment {response=}') return Comment(**response) if 'errors' not in response else None @protected_method(scope='comments') @@ -1354,7 +1352,7 @@ def update_comment(self, comment_id: int, data=Utils.generate_data_dict(dict_name='comment', body=body), request_type=RequestType.PATCH) logger.debug( - f'Detailed information about updating the comment: {response=}') + f'Detailed information about updating the comment {response=}') return Comment(**response) if 'errors' not in response else None @protected_method(scope='comments') @@ -1374,7 +1372,7 @@ def delete_comment(self, comment_id: int) -> bool: headers=self._authorization_header, request_type=RequestType.DELETE) logger.debug( - f'Detailed information about deleting the comment: {response=}') + f'Detailed information about deleting the comment {response=}') return 'notice' in response def anime_constants(self) -> AnimeConstants: @@ -1486,7 +1484,7 @@ def delete_dialog(self, user_id: Union[int, str]) -> bool: headers=self._authorization_header, request_type=RequestType.DELETE) logger.debug( - f'Detailed information about deleting the dialog: {response=}') + f'Detailed information about deleting the dialog {response=}') return 'notice' in response def users(self, From 6caacd51024bd4e57a23042d2618978765696238 Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 15 May 2022 13:58:37 +0300 Subject: [PATCH 13/13] bump version to 0.2.0 --- pyproject.toml | 2 +- shikithon/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 35f9090e..cef5036c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "shikithon" -version = "0.1.2" +version = "0.2.0" description = "Yet another Python wrapper for Shikimori API" authors = [ "SecondThundeR " diff --git a/shikithon/__init__.py b/shikithon/__init__.py index 6eed60b8..a786acd9 100644 --- a/shikithon/__init__.py +++ b/shikithon/__init__.py @@ -1,5 +1,5 @@ """Contains package version and some magic for importing API object.""" from shikithon.api import API -__version__ = '0.1.2' +__version__ = '0.2.0' __all__ = ['API']