"""Parent class for ows services.""" from typing import Optional from httpx import Response from lambdacommon.common_config import logger from owsclient import M2MTokenManager from owsclient import OwsClient from secrets_manager.python_ext import PythonSecretsManager from config import APPLICATION_NAME from config import ENVIRONMENT from config import OWS_CLIENT_TOKEN from config import TEST_ENVIRONMENT from src.constants.constants import DEFAULT_HEADERS from src.constants.constants import RequestMethod from src.utils.custom_dataclasses import InternalAttachmentPayload from src.utils.exceptions import OwsMoneyhubException class OwsMoneyhub: """Ows parent class on which clients will inherit.""" _secrets_manager = PythonSecretsManager(region_name='us-east-1') _m2m_token_manager = M2MTokenManager( secrets_manager=_secrets_manager, environment=ENVIRONMENT, service_name=APPLICATION_NAME, ) _service = 'ows-moneyhub' _ows_client = OwsClient( environment=ENVIRONMENT, service_name=APPLICATION_NAME, m2m_token_manager=_m2m_token_manager if ENVIRONMENT != TEST_ENVIRONMENT else None, ) @classmethod def create_internal_statement_attachment( cls, account_id: int, statement_period_id: int, payload: InternalAttachmentPayload, ) -> dict: """PUT request to update Statement attachment's file location value. Args: account_id (int): ID of the account statement_period_id (int): ID of the statement period payload (InternalAttachmentPayload): the attachment data. Returns: dict: Updated Statement Attachment object. """ path = f'/statement-attachment/account/{account_id}/statement-period/{statement_period_id}/internal-attachment' # noqa: E501 payload_serialised = payload.__dict__ return cls.post(path, payload_serialised) @classmethod def post(cls, path: str, body: dict) -> dict: """Make a PUT request and return the response. Args: path (str): the url of the request. body (dict): keyword arguments for the body of the request. Returns: dict: a json response in the form of a dict. """ response = cls._ows_client.post( cls._service, path=path, headers=cls._get_request_headers(), json=body ) return cls._process_request(path, RequestMethod.POST, response, body=body) @classmethod def _get_request_headers(cls) -> dict: """Get the headers for each request. Returns: dict: Request headers. """ headers = DEFAULT_HEADERS if OWS_CLIENT_TOKEN: headers['authorization'] = f'Bearer {OWS_CLIENT_TOKEN}' return headers @classmethod def _process_request( cls, path: str, method: RequestMethod, response: Response, params: Optional[dict] = None, body: Optional[dict] = None, ) -> dict: """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 (Optional[dict]): query params for the request. body (Optional[dict]): the body of the request being sent. Returns: dict: response data converted to json. """ headers = ' '.join([f'{h[0]}:{h[1]}' for h in DEFAULT_HEADERS.items()]) status = response.status_code body_contents = str(body) if body else '' text = response.text params_str = '?' + '&'.join([f'{k}={v}' for k, v in params.items()]) if params else '' logger.info(f'{method} {cls._service} {path}{params_str} ({headers}) {body_contents}') if response.status_code > 299: message = f'{cls._service} error: {status} response from {method.value} {path}{body_contents}: {text}' # noqa: E501 raise OwsMoneyhubException(message, status) data = response.json() logger.info(f'{response.status_code} ' + str(data)) return data