"""API utilities.""" import functools import os from flask import g from flask import request from marshmallow import ValidationError from asset_transcoder.constants import asset_upload as asset_upload_constants from asset_transcoder.utils.exceptions import OwsError def _get_request_context(): """Get global context.""" return g.request_context def get_user_id(): """Get user_id from global context.""" context = _get_request_context() if context.identity_uuid: return context.identity_uuid elif context.identity_id: return context.identity_id elif context.context_type == 'account' and context.orchard_user_id: return context.orchard_user_id raise OwsError(message='Failed to identify user', status=401) def get_app_by_object_type(object_type): """Get application name by object type.""" related_app = None for app, obj_types in asset_upload_constants.OBJECT_APP_RELATION.items(): if object_type in obj_types: related_app = app break if not related_app: raise OwsError.bad_request( 'object type {object_type} is not supported'.format( object_type=object_type)) return related_app def get_pipeline_config(object_type): """Get config object for lambda's pipeline.""" related_app = get_app_by_object_type(object_type) return { 'output_bucket_name': os.environ.get( 'OUTPUT_ASSETS_{0}_BUCKET_NAME'.format(related_app)), 'preview_bucket_name': os.environ.get( 'PREVIEW_ASSETS_{0}_BUCKET_NAME'.format(related_app)), 'elastic_transcoder_id': os.environ.get( 'ELASTIC_TRANSCODER_{0}_ID'.format(related_app)) } def utc_format(date): """Convert datetime to utc string.""" return date.isoformat() def utc_format_with_z(date): """Convert datetime to utc string.""" return utc_format(date) + '.000Z' 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 = request.get_json() try: validated = schema.load(data, partial=partial) except ValidationError as err: raise OwsError.bad_request(err.messages) else: return func(*args, data=validated, **kwargs) return wrapper return validator def validate_request_query(schema, partial=False): """Decorate requests' input query string 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 = request.args try: validated = schema.load(data, partial=partial) except ValidationError as err: raise OwsError.bad_request(err.messages) else: return func(*args, data=validated, **kwargs) return wrapper return validator def asset_url(filename, object_type): """Get full asset url for given objct type. Args: filename (str): uri part of url object_type (str): asset upload object type """ related_app = get_app_by_object_type(object_type) output_cdn = os.environ.get('OUTPUT_{0}_CDN'.format(related_app)) if not output_cdn: raise OwsError.bad_request('cdn value for {} not found'.format(object_type)) return 'https://{}/{}'.format(output_cdn, filename)