diff --git a/src/api.py b/src/api.py new file mode 100644 index 0000000..7211bda --- /dev/null +++ b/src/api.py @@ -0,0 +1,109 @@ + +import logging + +import aiohttp + +log = logging.getLogger(__name__) + + +class APIException(Exception): + pass + + +class NotCreatedException(APIException): + pass + +class BadStatusException(APIException): + pass + + +class API: + """Interactions with the API.""" + + API_HOST = "http://localhost:8000/" + API_ENDPOINT = API_HOST + "api/" + + RSS_FEED_ENDPOINT = API_ENDPOINT + "rssfeed/" + FEED_CHANNEL_ENDPOINT = API_ENDPOINT + "feedchannel/" + + def __init__(self, session: aiohttp.ClientSession): + log.debug("API session initialised") + self.session = session + self.token_headers = {"Authorization": f"Token 12bccad74fb8575b3242902014f8f3807016f4fe"} + + async def fetch_data(self, url: str, params=None): + log.debug("api fetching from url: %s", url) + async with self.session.get(url, params=params, headers=self.token_headers) as response: + return await response.json(), await response.text(), response.status + + async def send_data(self, url: str, data: dict): + log.debug("api posting to url: %s", url) + async with self.session.post(url, data=data, headers=self.token_headers) as response: + return await response.json(), await response.text(), response.status + + async def delete_data(self, url: str): + log.debug("api deleting to url %s", url) + async with self.session.delete(url, headers=self.token_headers) as response: + return await response.text(), response.status + + async def create_new_rssfeed(self, name: str, url: str, image_url: str, discord_server_id: int): + + log.debug("api creating rss feed: %s %s %s", name, url, image_url) + + async with self.session.get(image_url) as response: + image_data = await response.read() + + form = aiohttp.FormData() + form.add_field("name", name) + form.add_field("url", url) + form.add_field("image", image_data, filename="file.jpg") + form.add_field("discord_server_id", str(discord_server_id)) + + resp_json, resp_text, resp_status = await self.send_data(self.RSS_FEED_ENDPOINT, form) + + if resp_status != 201: + log.error(resp_text) + raise NotCreatedException(f"Expected HTTP 201, not HTTP {response.status} - {resp_text}") + + log.debug(resp_text) + + return resp_json + + async def get_rssfeed(self, uuid: str) -> dict: + + log.debug("api getting rss feed") + + endpoint = f"{self.RSS_FEED_ENDPOINT}{uuid}" + resp_json, resp_text, resp_status = await self.fetch_data(endpoint) + + if resp_status != 200: + log.error(resp_text) + raise BadStatusException(f"Expected HTTP 200, not HTTP {resp_status} - {resp_text}") + + return resp_json + + async def get_rssfeed_list(self, **filters) -> dict: + + log.debug("api getting list of rss feed") + + resp_json, resp_text, resp_status = await self.fetch_data(self.RSS_FEED_ENDPOINT, params=filters) + + if resp_status != 200: + log.error(resp_text) + raise BadStatusException(f"Expected HTTP 200, not HTTP {resp_status} - {resp_text}") + + log.debug(resp_text) + + return resp_json["results"], resp_json["count"] + + async def delete_rssfeed(self, uuid: str): + + log.debug("api deleting rss feed") + + resp_text, resp_status = await self.delete_data(f"{self.RSS_FEED_ENDPOINT}{uuid}/") + + if resp_status != 204: + log.error(resp_text) + raise BadStatusException(f"Expected HTTP 204, not HTTP {resp_status} - {resp_text}") + + log.debug(resp_text)