"""Application Handlers. Requests are redirected to handlers, which are responsible for getting information from the URL and passing it down to the logic layer. The way each layer talks to each other is through Response objects which defines the type status of the data and the data itself. Please note: the Orchard uses the term handlers over views as convention for clarity See: oto.response for more details. """ from flask import Response, g, jsonify, request from owsresponse import response from owsresponse.adaptors.flask import flaskify from transcoding import config from transcoding.api import app from transcoding.constants import field_const from transcoding.logic import ( create_transcoding, preset, transcoding_job as transcoding_job_logic, transcoding_order, transcoding_status, ) from transcoding.validation import json_schema from transcoding.validation.schema import body @app.route(config.HEALTH_CHECK, methods=["GET"]) def health() -> Response: """Check the health of the application.""" return jsonify({"status": "ok"}) @app.errorhandler(Exception) def exception_handler(error: Exception) -> Response: """Return response when uncaught exception is raised. Note: Exception will also be sent to Sentry if config.SENTRY is set. Returns: flask.Response: A 500 response with JSON 'code' & 'message' payload. """ message = ( "The server encountered an internal error " "and was unable to complete your request." ) g.log.exception(error) return flaskify(response.create_fatal_response(message)) @app.route("/transcoding/presets", methods=["GET"]) def get_all_presets() -> Response: """Return the list of existing transcoding presets. Returns: flask.Response: Response contain list of preset entries. """ return flaskify(preset.get_all_presets()) @app.route("/transcoding/preset/", methods=["POST"]) @json_schema.validate_body(request, body.post_transcoding_by_preset_schema) def create_preset_transcoding(preset_alias: str) -> Response: """Start transcoding workflow by rules associated with preset. Args: preset_alias (str): Alias for preset. Returns: flask.Response: Response contain transcoding_order id and status. Raises: botocore.exceptions.ClientError: raise the exception when error code isn't an equal to 404 """ request_body = request.get_json(silent=True) or {} input_data = request_body.get("input") or {} return flaskify( create_transcoding.create_transcoding_by_preset( input_bucket=input_data.get("bucket", ""), input_key=input_data.get("key", ""), preset_alias=preset_alias, status_topic_alias=request_body.get("status_topic_alias"), source_asset_metadata=input_data.get("metadata"), ) ) @app.route("/transcoding-order//status", methods=["GET"]) def get_transcoding_status(transcoding_order_id: int) -> Response: """Return the list of existing transcoding presets. Args: transcoding_order_id (int): Transcoding Order id. Returns: flask.Response: Response contain transcoding order and related jobs statuses. """ return flaskify( transcoding_order.get_status(transcoding_order_id=transcoding_order_id) ) @app.route("/transcoding-job//status", methods=["POST"]) @json_schema.validate_body(request, body.post_transcoding_job_status_schema) def set_transcoding_job_status(transcoding_job_id: int) -> Response: """Save status of transcoding job processing. Args: transcoding_job_id (int): Transcoding job id. Returns: flask.Response: Response contain transcoding_order id and status. """ request_body = request.get_json(silent=True) or {} return flaskify( transcoding_status.process_transcoding_status( transcoding_job_id=int(transcoding_job_id), status=request_body.get(field_const.STATUS, ""), status_description=request_body.get(field_const.STATUS_DESCRIPTION), metadata=request_body.get( field_const.METADATA, {"Duration": request_body.get(field_const.DURATION, 0) / 1000}, ), ) ) @app.route("/transcoding-job/", methods=["GET"]) def get_transcoding_job(transcoding_job_id: int) -> Response: """Return the existing transcoding job entry by id. Args: transcoding_job_id (int): Transcoding job id. Returns: flask.Response: Response contain transcoding job entry. """ return flaskify( transcoding_job_logic.get_transcoding_job_by_id( transcoding_job_id=transcoding_job_id ) )