"""Parent class for ows services.""" from typing import TypeVar from audience_common.m2m_token import M2MTokenManager from audience_common.secretsmanager import SecretsManager from httpx import Response from owsclient import OwsClient from moneyhub.config import Config from moneyhub.constants.constants import DEFAULT_HEADERS from moneyhub.constants.constants import OK_RESPONSE from moneyhub.constants.constants import RequestMethod from moneyhub.constants.constants import SUCCESS_UPPER_BOUNDARY from moneyhub.utils.exceptions import OwsServiceException APPLICATION_NAME = 'Jenkins Script' T = TypeVar('T') class OwsService: """Ows parent class on which clients will inherit.""" _secrets_manager = SecretsManager(region_name='us-east-1') _m2m_token_manager = M2MTokenManager( secrets_manager=_secrets_manager, secret_name_key=f'{Config.ENVIRONMENT}/lambda-jwt-refresh/jwt_token', secret_expire_name_key=f'{Config.ENVIRONMENT}/lambda-jwt-refresh/jwt_token_expiration', ) _ows_client = OwsClient( environment=Config.ENVIRONMENT, service_name=APPLICATION_NAME, m2m_token_manager=_m2m_token_manager if Config.ENVIRONMENT != Config.TEST_ENVIRONMENT else None ) _service = '' @classmethod def post( cls, path: str, body: dict | list | None = None, params: dict | None = None ) -> dict | list | None: """Make a PUT request and return the response. Args: path (str): the url of the request. body (dict | list): keyword arguments for the body of the request. params (dict): the query string parameters. Returns: dict: a json response in the form of a dict. """ response = cls._ows_client.post( cls._service, path=path, headers=DEFAULT_HEADERS, json=body, params=params, timeout=30.0) return cls._process_request(path, RequestMethod.POST, response, params, body) @classmethod def _process_request( cls, path: str, method: RequestMethod, response: Response, params: dict | None, body: dict | list | None ) -> dict | list | None: """Process a request by logging it, checking the response status and returning it. Args: path (str): the path of the request. method (RequestMethod): the request method. response (Response): the response returned from the endpoint. params (dict): query parameters. body (dict | list): the body of the request being sent. Returns: dict: response data converted to json. """ if params: path += '?' + '&'.join(f'{k}={v}' for k, v in params.items()) text = response.text status = response.status_code if status < OK_RESPONSE or status > SUCCESS_UPPER_BOUNDARY: message = f'{cls._service} error: {status} response from {method.value} {path} ' \ f'{body or ""}: {text}' raise OwsServiceException(message, response.status_code) return response.json() @classmethod def validate_response_type(cls, response: dict | list | None, expected_type: type[T]) -> T: """Validate that the response is in the expected type. Args: response (dict | list): response to validate expected_type (Type[T]): the type we expect the response to be Returns: T: the response as expected type """ if not isinstance(response, expected_type): raise OwsServiceException( f'{cls._service} error: Unexpected response type {type(response)}', 500) return response