from http import HTTPStatus from typing import Any, Dict, List, Union import requests from smelog.factory import BoundLogger from apollo_save_push_receipts import exceptions from apollo_save_push_receipts.config import Config as config from apollo_save_push_receipts.constants import APP_SLUG class UserDataClient: def __init__(self, logger: BoundLogger): self.logger = logger self._session = None self.base_url = f"{config.USER_DATA_SCHEMA}://{config.USER_DATA_HOST}" def session(self): if not self._session: self._session = requests.Session() self._session.headers.update({"Authorization": config.USER_DATA_APIKEY}) return self._session def _send_request(self, request: requests.Request) -> Union[List[dict], dict]: retry_counter = 0 request_method = request.method result = None while True: try: session = self.session() response = session.send(session.prepare_request(request), timeout=config.USER_DATA_TIMEOUT) except (ConnectionError, requests.Timeout) as exc: if retry_counter >= config.USER_DATA_RETRY_COUNT: raise exceptions.UserDataUnavailable from exc self.logger.info( f"{retry_counter}/{config.USER_DATA_RETRY_COUNT} Got exception {exc} on request to {request.url}." ) retry_counter += 1 continue if request_method == "GET": try: result = response.json() except ValueError: raise exceptions.UserDataInvalidResponse(status_code=response.status_code) if response.status_code != HTTPStatus.OK: raise exceptions.UserDataInvalidResponse(response_data=result, status_code=response.status_code) return result def update_bulk(self, data: List[Dict[str, Any]]): url = f"{self.base_url}/api/service/messages/push/" request = requests.Request("PUT", url, json={"data": data}, headers={"X-App-Slug": APP_SLUG}) return self._send_request(request) def deactivate_bulk(self, data: List[Dict[str, Any]]): url = f"{self.base_url}/api/users/devices/unregister/" request = requests.Request("PUT", url, json={"data": data}, headers={"X-App-Slug": APP_SLUG}) return self._send_request(request)