from aiohttp import ClientSession from typing import Any, Collection, Dict import logging from aiohttp.web import HTTPNotFound from server.core.helpers.authorization import BaseClient from server.user_service.exceptions import UserServiceError from server.user_service.client import APPLICATION_BODY, Config log = logging.getLogger(__name__) class UserServiceClient(BaseClient): """Apollp API app_client.""" dna_prefix = "sme-dna|" error_cls = UserServiceError method_mapper = { "POST": "_post", "DELETE": "_delete", } def __init__(self, session: ClientSession, config: Config): super().__init__(session, config) self.headers.update({"X-App-Slug": "dna"}) async def check_health(self): return True def __update_user_id(self, user_id: str) -> str: return user_id if self.dna_prefix in user_id else self.dna_prefix + user_id async def _make_end_url(self, url): return self.config.user_service_url + url async def _get(self, end_url: str, method: str = "GET"): return await super()._make_request(end_url, method) async def _post(self, end_url: str, data: Dict[str, Any], method: str = "POST"): return await super()._make_request(end_url, method, body=data) async def _put(self, end_url: str, data: Dict[str, Any], method: str = "PUT"): return await super()._make_request(end_url, method, body=data) async def _delete(self, end_url: str, data: Dict[str, Any], method: str = "DELETE"): return await super()._make_request(end_url, method, body=data) async def _create_application(self, data: Dict[str, Any]): url = f"service/applications/" end_url = await self._make_end_url(url) return await self._post(end_url, data) async def _get_application(self, slug: Collection[str] = APPLICATION_BODY["slug"]): url = f"service/applications/?slug={slug}" end_url = await self._make_end_url(url) application = None try: application = await self._get(end_url) except UserServiceError as error: if error.status_code == HTTPNotFound.status_code: log.warning(f"'{slug}' application does not exist") log.warning(f"creating '{slug}' application...") application = await self._create_application(APPLICATION_BODY) except Exception as e: log.error("Can't get application from apollo due to {e}") raise e return application async def _get_account(self, user_id: str, get_or_create: bool = True): url = "v2/accounts/" end_url = await self._make_end_url(url) end_url += f"?user_id={user_id}&get_or_create={get_or_create}" return await self._get(end_url) async def _manage_favorites(self, user_id: str, data: Dict, end_url: str, method: str = "POST"): account = await self._get_account(user_id) if "list" in end_url: data.update(dict(account=dict(id=[account["id"]]))) else: data.update(dict(account_id=account["id"])) _method = getattr(self, self.method_mapper[method]) return await _method(end_url, data) async def list_favorites(self, user_id: str, data: Dict): url = "service/users/favorites/list/" end_url = await self._make_end_url(url) return await self._manage_favorites(user_id, data, end_url, "POST") async def add_entity_to_account_favorites(self, user_id: str, data: Dict[str, Any]): url = "v2/accounts/favorites/" end_url = await self._make_end_url(url) return await self._manage_favorites(user_id, data, end_url, "POST") async def delete_entity_from_account_favorites(self, user_id: str, data: Dict[str, Any]): url = "v2/accounts/favorites/" end_url = await self._make_end_url(url) return await self._manage_favorites(user_id, data, end_url, "DELETE")