PYRSS-Bot/src/api.py

128 lines
3.9 KiB
Python

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, api_token: str, session: aiohttp.ClientSession):
log.debug("API session initialised")
self.session = session
self.token_headers = {"Authorization": f"Token {api_token}"}
async def make_request(self, method: str, url: str, **kwargs) -> dict:
"""Make a request to the given API endpoint.
Args:
method (str): The request method to use, examples: GET, POST, DELETE...
url (str): The API endpoint to request to.
**kwargs: Passed into self.session.request.
Returns:
dict: Dictionary containing status code, json or text.
"""
async with self.session.request(method, url, headers=self.token_headers, **kwargs) as response:
response.raise_for_status()
try:
json = await response.json()
text = None
except aiohttp.ContentTypeError:
json = None
text = await response.text()
status = response.status
return {"json": json, "text": text, "status": status}
async def create_new_rssfeed(self, name: str, url: str, image_url: str, discord_server_id: int) -> dict:
"""Create a new RSS Feed.
Args:
name (str): Name of the RSS Feed.
url (str): URL for the RSS Feed.
image_url (str): URL of the image representation of the RSS Feed.
discord_server_id (int): ID of the discord server behind this item.
Returns:
dict: JSON representation of the newly created RSS Feed.
"""
log.debug("creating rssfeed: %s %s %s %s", name, url, image_url, discord_server_id)
async with self.session.get(image_url) as response:
image_data = await response.read()
# Using formdata to make the image transfer easier.
form = aiohttp.FormData({
"name": name,
"url": url,
"discord_server_id": discord_server_id
})
form.add_field("image", image_data, filename="file.jpg")
data = (await self.make_response("POST", self.RSS_FEED_ENDPOINT, data=form))["json"]
return data
async def get_rssfeed(self, uuid: str) -> dict:
"""Get a particular RSS Feed given it's UUID.
Args:
uuid (str): Identifier of the desired RSS Feed.
Returns:
dict: A JSON representation of the RSS Feed.
"""
log.debug("getting rssfeed: %s", uuid)
endpoint = f"{self.RSS_FEED_ENDPOINT}/{uuid}/"
data = (await self.make_request("GET", endpoint))["json"]
return data
async def get_rssfeed_list(self, **filters) -> tuple[list[dict], int]:
"""Get all RSS Feeds with the associated filters.
Returns:
tuple[list[dict], int] list contains dictionaries of each item, int is total items.
"""
log.debug("getting list of rss feeds with filters: %s", filters)
data = (await self.make_request("GET", self.RSS_FEED_ENDPOINT, params=filters))["json"]
return data["results"], data["count"]
async def delete_rssfeed(self, uuid: str) -> int:
"""Delete a specified RSS Feed.
Args:
uuid (str): Identifier of the RSS Feed to delete.
Returns:
int: Status code of the response.
"""
log.debug("deleting rssfeed: %s", uuid)
endpoint = f"{self.RSS_FEED_ENDPOINT}/{uuid}/"
status = (await self.make_request("DELETE", endpoint))["status"]
return status