"""API utilities.""" import functools from copy import deepcopy from typing import Callable from abacus_common_data.country import Country from flask import g, request from marshmallow import ValidationError from owsresponse import response from owsresponse.adaptors.flask import flaskify from account.connectors.sentry import sentry_client from account.constants import error def jwt_check(func: Callable): """Check for a valid jwt.""" @functools.wraps(func) def decorator(**kwargs): identity_uuid = g.request_context.jwt_identity_id if not identity_uuid: return flaskify( response.create_error_response( error.ERROR_CODE_AUTHORIZATION, message='Request context has no identity uuid.', status=401, ) ) return func(**kwargs) return decorator def validate_request_data(schema, partial=False): """Decorate requests' input data validation. Args: schema (marshmallow.Schema()): schema instance to apply partial (bool): validate only derived fields """ def validator(func): @functools.wraps(func) def wrapper(*args, **kwargs): data = {} try: if request.method == 'GET': # Handle query parameters for GET requests data = dict(request.args) elif request.method in ['POST', 'PUT', 'PATCH']: # Handle JSON body for POST, PUT, PATCH requests json_data = request.get_json(silent=True) or {} data = deepcopy(json_data) data.update(kwargs) kwargs['deserialize_schema'] = schema.load(data, partial=partial) except ValidationError as err: sentry_client.capture_exception() return flaskify( response.create_error_response( code=error.ERROR_CODE_VALIDATION_ERROR, message=err.messages ) ) except AttributeError as err: sentry_client.capture_exception() return flaskify( response.create_error_response( code=error.ERROR_CODE_VALIDATION_ERROR, message=str(err) ) ) else: return func(*args, **kwargs) return wrapper return validator def validate_country_code(country_code): """Validate a country code parameter.""" try: Country(country_code.upper()) return country_code except KeyError: raise ValidationError(error.ERROR_MESSAGE_UNKNOWN_COUNTRY.format(code=country_code))