def search(self, search_type, query, page=None, key=None, value=None): """ Searches for a query on MyAnimeList Keyword Arguments: search_type -- where to search (anime, manga, person, character) query -- query to search for page -- page number of the results (default None) key -- key for ?key=value URL query (default None) value -- value for ?key=value URL query (default None) """ url = self.search_base.format(search_type=search_type, query=query) # Check if page and query are valid if page is not None: if not isinstance(page, int): raise ClientException('The parameter \'page\' must be an integer') url += '/' + page if key is not None: if value is None: raise ClientException('You need to pass a value with the key') values = SEARCH_PARAMS.get(key, d=None) if values is None: raise ClientException('The key is not valid') elif isinstance(values, list) and value not in values: raise ClientException('The value is not valid') url += '?' + key + '=' + value # Get information from the API response = session.get(url) # Check if there's an error with the response kwargs = {'search type': search_type, 'query': query} self._check_response(response, **kwargs) return response.json()
def top(self, type, page=None, subtype=None): """ Gets top items on MyAnimeList Keyword Arguments: type -- type to get top items from (anime, manga) page -- page number of the results (default None) subtype -- subtype to get filtered top items, possible values in docs """ url = self.top_base.format(type=type.lower()) # Check if type is valid if type.lower() not in SUBTYPES: raise ClientException('Type must be anime or manga') # Check if page is valid if page is not None: if not isinstance(page, int): raise ClientException('The parameter \'page\' must be an integer') url += '/' + page # Check if subtype is valid if subtype is not None: if subtype.lower() not in SUBTYPES[type.lower()]: raise ClientException('Subtype is not valid for ' + type) url += '/' + subtype.lower() # Get information from the API response = session.get(url) # Check if there's an error with the response self._check_response(response, type=type) return response.json()
def _get_meta_url( self, request: str, type: Optional[str], period: Optional[str], offset: Optional[int], ) -> str: """Create URL for meta endpoint""" url: str = self.meta_base.format(request=request) # Check if request is valid if request not in META["request"]: raise ClientException("Request must be 'requests' or 'status'") if request == "status" and (type is not None or period is not None or offset is not None): raise ClientException( "There is no type or period for the 'status' request") if request == "requests": if type not in META["type"]: raise ClientException("Type is not valid") if period not in META["period"]: raise ClientException( "Period must be 'today', 'weekly', or 'monthly'") url += "/" + type + "/" + period url = self._add_page_to_url(url, offset) return url
def _get_search_url( self, search_type: str, query: str, page: Optional[int], parameters: Optional[Mapping[str, Optional[Union[int, str, float]]]], ) -> str: """Create URL for search endpoint""" url: str = self.search_base.format(search_type=search_type, query=query) url = self._add_page_to_url(url, page, delimiter="&page=") if parameters is not None: if search_type.lower() not in ("anime", "manga"): raise ClientException( "Parameters are only for anime or manga search") url += "&" for key, value in parameters.items(): if key == "rated" and search_type.lower() == "manga": raise ClientException( "rated parameter only for anime search") if key in ("type", "status", "rated", "genre", "order_by"): values = SEARCH_PARAMS[search_type][key] # type: ignore else: values = SEARCH_PARAMS.get(key) if values is None: raise ClientException("The key is not valid") elif key == "genre" and isinstance(value, str): genres = value.split(",") for genre in genres: if int(genre) not in values: raise ClientException("Invalid genre passed in") elif isinstance(values, tuple) and value not in values: raise ClientException("The value is not valid") url += key + "=" + str(value) + "&" return url
def _get_genre_url(self, type, genre_id, page): """Create URL for genre endpoint""" url = self.genre_base.format(type=type.lower(), genre_id=genre_id) # Check if type is valid if type.lower() not in GENRE_TYPES: raise ClientException('Type must be anime or manga') if not isinstance(genre_id, int): raise ClientException('ID must be an integer') url = self._add_page_to_url(url, page) return url
def _get_genre_url(self, type: str, genre_id: int, page: Optional[int]) -> str: """Create URL for genre endpoint""" url: str = self.genre_base.format(type=type.lower(), genre_id=genre_id) # Check if type is valid if type.lower() not in GENRE_TYPES: raise ClientException("Type must be anime or manga") if not isinstance(genre_id, int): raise ClientException("ID must be an integer") url = self._add_page_to_url(url, page) return url
def _get_creator_url(self, creator_type, creator_id, page): """Create URL for producer and magazine endpoints""" url = self.creator_base.format(creator_type=creator_type.lower(), creator_id=creator_id) # Check if type is valid if creator_type.lower() not in CREATOR_TYPES: raise ClientException('Type must be producer or magazine') if not isinstance(creator_id, int): raise ClientException('ID must be an integer') url = self._add_page_to_url(url, page) return url
def _get_meta_url(self, request, type, period): """Create URL for meta endpoint""" url = self.meta_base.format(request=request, type=type, period=period) # Check if request is valid if request not in META['request']: raise ClientException('Request must be \'requests\' or \'status\'') if type not in META['type']: raise ClientException('Type is not valid') if period not in META['period']: raise ClientException( 'Period must be \'today\', \'weekly\', or \'monthly\'') return url
def _get_search_url(self, search_type, query, page, parameters): """Create URL for search endpoint""" url = self.search_base.format(search_type=search_type, query=query) url = self._add_page_to_url(url, page, delimiter='&page=') if parameters is not None: url += '?' for key, value in parameters.items(): values = SEARCH_PARAMS.get(key) if values is None: raise ClientException('The key is not valid') elif isinstance(values, tuple) and value not in values: raise ClientException('The value is not valid') url += key + '=' + str(value) + "&" return url
def _get_top_url(self, type, page, subtype): """Create URL for top endpoint""" url = self.top_base.format(type=type.lower()) # Check if type is valid if type.lower() not in SUBTYPES: raise ClientException('Type must be anime or manga') url = self._add_page_to_url(url, page) # Check if subtype is valid if subtype is not None: if page is None: raise ClientException('Page is required if subtype is given') if subtype.lower() not in SUBTYPES[type.lower()]: raise ClientException('Subtype is not valid for ' + type) url += '/' + subtype.lower() return url
def _get_season_url(self, year: int, season: str) -> str: """Create URL for season endpoint""" url: str = self.season_base.format(year=year, season=season.lower()) # Check if year and season are valid if not (isinstance(year, int) and season.lower() in SEASONS): raise ClientException("Season or year is not valid") return url
def _get_top_url(self, type: str, page: Optional[int], subtype: Optional[str]) -> str: """Create URL for top endpoint""" url: str = self.top_base.format(type=type.lower()) # Check if type is valid if type.lower() not in SUBTYPES: raise ClientException("Type must be anime or manga") url = self._add_page_to_url(url, page) # Check if subtype is valid if subtype is not None: if page is None: raise ClientException("Page is required if subtype is given") if subtype.lower() not in SUBTYPES[type.lower()]: raise ClientException("Subtype is not valid for " + type) url += "/" + subtype.lower() return url
def _add_page_to_url(self, url, page, delimiter='/'): """Add page to URL if it exists and is valid""" if page is not None: if not isinstance(page, int): raise ClientException( 'The parameter \'page\' must be an integer') url += delimiter + str(page) return url
def _add_page_to_url( self, url: str, page: Optional[int], delimiter: str = "/" ) -> str: """Add page to URL if it exists and is valid""" if page is not None: if not isinstance(page, int): raise ClientException("The parameter 'page' must be an integer") url += delimiter + str(page) return url
def _get_user_url( self, username: str, request: Optional[str], argument: Optional[Union[int, str]], page: Optional[int], parameters: Optional[Mapping], ) -> str: """Create URL for user endpoint""" url: str = self.user_base.format(username=username.lower()) if request is not None: if request not in USER_REQUESTS: raise ClientException("Invalid request for user endpoint") url += "/" + request if request.lower() == "profile" and argument is not None: raise ClientException("No argument should be given for profile request") if ( request.lower() in ("animelist", "mangalist") and argument is None and page is not None ): raise ClientException( "You must provide an argument if you provide a page for animelist or mangalist" ) if argument is not None: if request.lower() == "friends" and not isinstance(argument, int): raise ClientException( "Argument for friends request must be a page number integer" ) if isinstance(argument, str): if ( request.lower() == "history" and argument.lower() not in USER_HISTORY_ARGUMENTS ): raise ClientException( "Argument for history request should be anime or manga" ) if ( request.lower() == "animelist" and argument.lower() not in USER_ANIMELIST_ARGUMENTS ): raise ClientException( "Argument for animelist request is not valid" ) if ( request.lower() == "mangalist" and argument.lower() not in USER_MANGALIST_ARGUMENTS ): raise ClientException( "Argument for mangalist request is not valid" ) url += "/" + str(argument) if request.lower() in ("animelist", "mangalist"): url = self._add_page_to_url(url, page) if parameters is not None: url += "?" for key, value in parameters.items(): url += key + "=" + str(value) + "&" return url
def _get_schedule_url(self, day): """Create URL for schedule endpoint""" url = self.schedule_base # Check if day is valid if day is not None: if day.lower() not in DAYS: raise ClientException('Day is not valid') else: url += '/' + day.lower() return url
def _get_schedule_url(self, day: Optional[str]) -> str: """Create URL for schedule endpoint""" url: str = self.schedule_base # Check if day is valid if day is not None: if day.lower() not in DAYS: raise ClientException("Day is not valid") else: url += "/" + day.lower() return url
def _get_url(self, endpoint, id, extension, page): """Create URL for anime, manga, character, person, and club endpoints""" url = self.base.format(endpoint=endpoint, id=id) # Check if extension is valid if extension is not None: if extension not in EXTENSIONS[endpoint]: raise ClientException('The extension is not valid') url += '/' + extension if extension in ('episodes', 'reviews', 'userupdates', 'members'): url = self._add_page_to_url(url, page) return url
def _get_url(self, endpoint: str, id: int, extension: Optional[str], page: Optional[int]) -> str: """Create URL for anime, manga, character, person, and club endpoints""" url: str = self.base.format(endpoint=endpoint, id=id) # Check if extension is valid if extension is not None: if extension not in EXTENSIONS[endpoint]: raise ClientException("The extension is not valid") url += "/" + extension if extension in ("episodes", "reviews", "userupdates", "members"): url = self._add_page_to_url(url, page) return url
def meta(self, request, type, period): """ Gets meta information regarding the Jikan REST API Keyword Arguments: request -- requests (requests, status) type -- type to get info on, possible values in docs period -- time period (today, weekly, monthly) """ url = self.meta_base.format(request=request, type=type, period=period) # Check if request is valid if request not in META['request']: raise ClientException('Request must be \'requests\' or \'status\'') if type not in META['type']: raise ClientException('Type is not valid') if period not in META['period']: raise ClientException('Period must be \'today\', \'weekly\', or \'monthly\'') # Get information from the API response = session.get(url) # Check if there's an error with the response self._check_response(response, request=request, type=type, period=period) return response.json()
def season(self, year, season): """ Gets information on anime of the specific season Keyword Arguments: year -- year to get anime of season -- season to get anime of (winter, spring, summer, fall) """ url = self.season_base.format(year=year, season=season.lower()) # Check if year and season are valid if not (isinstance(year, int) and season.lower() in SEASONS): raise ClientException('Season or year is not valid') # Get information from the API response = session.get(url) # Check if there's an error with the response self._check_response(response, year=year, season=season) return response.json()
def schedule(self, day=None): """ Gets anime scheduled for the specific day Keyword Arguments: day -- day to get anime of (default None) """ url = self.schedule_base # Check if day is valid if day is not None: if day.lower() not in DAYS: raise ClientException('Day is not valid') else: url += '/' + day.lower() # Get information from the API response = session.get(url) # Check if there's an error with the response self._check_response(response, day=day) return response.json()
def _get(self, endpoint, id, extension, page=None): """ Gets the response from Jikan API given the endpoint Keyword Arguments: endpoint -- endpoint of API (anime, manga, character, person) id -- id of what to get the information of extension -- special information to get, possible values in the docs page -- page number of the results (default None) """ url = self.base.format(endpoint=endpoint, id=id) # Check if extension is valid if extension is not None: if extension not in EXTENSIONS[endpoint]: raise ClientException('The extension is not valid') url += '/' + extension if extension == 'episodes' and isinstance(page, int): url += '/' + page # Get information from the API response = session.get(url) # Check if there's an error with the response self._check_response(response, id=id, endpoint=endpoint) return response.json()
def _get_user_url(self, username, request, argument, page): """Create URL for user endpoint""" url = self.user_base.format(username=username.lower()) if request is not None: if request not in USER_REQUESTS: raise ClientException('Invalid request for user endpoint') url += '/' + request if request.lower() == 'profile' and argument is not None: raise ClientException( 'No argument should be given for profile request') if request.lower() in ('animelist', 'mangalist' ) and argument is None and page is not None: raise ClientException( 'You must provide an argument if you provide a page for animelist or mangalist' ) if argument is not None: if request.lower() == 'history' and argument.lower( ) not in USER_HISTORY_ARGUMENTS: raise ClientException( 'Argument for history request should be anime or manga' ) if request.lower() == 'friends' and not isinstance( argument, int): raise ClientException( 'Argument for friends request must be a page number integer' ) if request.lower() == 'animelist' and argument.lower( ) not in USER_ANIMELIST_ARGUMENTS: raise ClientException( 'Argument for animelist request is not valid') if request.lower() == 'mangalist' and argument.lower( ) not in USER_MANGALIST_ARGUMENTS: raise ClientException( 'Argument for mangalist request is not valid') url += '/' + str(argument) if request.lower() in ('animelist', 'mangalist'): url = self._add_page_to_url(url, page) return url