diff --git a/Existing_API_Collection/Anime Api/README.md b/Existing_API_Collection/Anime Api/README.md new file mode 100644 index 0000000..eff8464 --- /dev/null +++ b/Existing_API_Collection/Anime Api/README.md @@ -0,0 +1,3 @@ +## Anime Facts Rest API + +The Anime Facts Rest API is an API written in Node.js to get anime facts. diff --git a/Existing_API_Collection/Anime Api/Src/__init__.py b/Existing_API_Collection/Anime Api/Src/__init__.py new file mode 100644 index 0000000..bbb6edb --- /dev/null +++ b/Existing_API_Collection/Anime Api/Src/__init__.py @@ -0,0 +1,72 @@ +""" +Base module for the anime facts rest api. The API documentation can be found at +https://chandan-02.github.io/anime-facts-rest-api/ + +Mantainer of the API: Chandan Kumar (https://github.com/chandan-02) +""" +import typing, requests, random + +from anime_api import exceptions +from anime_api.apis.anime_facts_rest_api.objects import Anime, Fact + + +class AnimeFactsRestAPI: + """ + Docs: https://chandan-02.github.io/anime-facts-rest-api/ + """ + + endpoint = "https://anime-facts-rest-api.herokuapp.com/api/v1" + + def get_animes(self) -> typing.List[Anime]: + """ + Returns a list of all animes. + """ + response = requests.get(self.endpoint) + + if response.status_code != 200: + raise exceptions.ServerError( + status_code=response.status_code, + ) + + return [ + Anime( + id=anime["anime_id"], + name=anime["anime_name"], + image=anime["anime_img"], + ) + for anime in response.json()["data"] + ] + + def get_anime_facts(self, anime_name: str) -> typing.List[Fact]: + """ + Returns a list of facts about the given anime (by it's name). + """ + response = requests.get(f"{self.endpoint}/{anime_name}") + + if response.status_code != 200: + raise exceptions.ServerError( + status_code=response.status_code + ) + + return [ + Fact(id=fact["fact_id"], fact=fact["fact"]) for fact in response.json()["data"] + ] + + def get_anime_random_fact(self, anime_name: str) -> Fact: + """ + Return a random fact about the given anime (by it's name). + """ + return random.choice(self.get_anime_facts(anime_name)) + + def get_fact(self, anime_name: str, fact_id: int) -> Fact: + """ + Returns a specific Fact by it's ID and it's anime's name. + """ + response = requests.get(f"{self.endpoint}/{anime_name}/{fact_id}") + + if response.status_code != 200: + raise exceptions.ServerError( + status_code=response.status_code, + ) + + return Fact(id=response.json()["data"]["fact_id"], fact=response.json()["data"]["fact"]) diff --git a/Existing_API_Collection/Anime Api/Src/objects.py b/Existing_API_Collection/Anime Api/Src/objects.py new file mode 100644 index 0000000..3c668aa --- /dev/null +++ b/Existing_API_Collection/Anime Api/Src/objects.py @@ -0,0 +1,41 @@ +from dataclasses import dataclass + +import typing + + +@dataclass +class Anime: + """ + Object representation of an anime + """ + + id: int + name: str + image: str + + @property + def facts(self): + """ + Returns a list of facts about the anime. + """ + from anime_api.apis import AnimeFactsRestAPI + + api = AnimeFactsRestAPI() + + return api.get_anime_facts(self.name) + + def __str__(self): + return self.name.replace('_', ' ').title() + + +@dataclass +class Fact: + """ + Object representation of an anime fact + """ + + id: int + fact: str + + def __str__(self): + return self.fact diff --git a/Existing_API_Collection/Anime Api/Tests/test_anime_facts_rest_api.py b/Existing_API_Collection/Anime Api/Tests/test_anime_facts_rest_api.py new file mode 100644 index 0000000..9c6e4bf --- /dev/null +++ b/Existing_API_Collection/Anime Api/Tests/test_anime_facts_rest_api.py @@ -0,0 +1,52 @@ +""" +Run tests for the AnimeFactsRestAPI class. + +Usage: + cd tests + poetry run python -m pytest anime_facts_rest_api.py +""" + +import typing + +from anime_api.apis.anime_facts_rest_api import AnimeFactsRestAPI +from anime_api.apis.anime_facts_rest_api.objects import Anime, Fact + + +def test_get_animes(): + """ + Test the get_animes method. Should return a list of animes. + """ + animes: typing.List[Anime] = AnimeFactsRestAPI().get_animes() + + assert isinstance( + animes, list + ), "The return type of get_animes() is not a list." + assert len(animes) > 0, "The list of animes is empty." + assert isinstance( + animes[0], Anime + ), "The list of animes does not contain objects.Anime objects." + + +def test_get_anime_facts(): + """ + Test the get_anime_facts method. Should return a list of facts. + """ + facts: typing.List[Fact] = AnimeFactsRestAPI().get_anime_facts(anime_name="naruto") + + assert isinstance( + facts, list + ), "The return type of get_anime_facts() is not a list." + assert len(facts) > 0, "The list of facts is empty." + assert isinstance( + facts[0], Fact + ), "The list of facts does not contain objects.Fact objects." + +def test_get_fact(): + """ + Test the get_fact method. Should return a single fact. + """ + fact: Fact = AnimeFactsRestAPI().get_fact(anime_name="naruto", fact_id=1) + + assert isinstance( + fact, Fact + ), "The return type of get_fact() is not a objects.Fact object."