from flask import Blueprint, jsonify, request from sqlalchemy.exc import SQLAlchemyError from app.dao.service_callback_api_dao import ( delete_service_callback_api, get_service_callback_api, reset_service_callback_api, save_service_callback_api, ) from app.dao.service_inbound_api_dao import ( delete_service_inbound_api, get_service_inbound_api, reset_service_inbound_api, save_service_inbound_api, ) from app.enums import CallbackType from app.errors import InvalidRequest, register_errors from app.models import ServiceCallbackApi, ServiceInboundApi from app.schema_validation import validate from app.service.service_callback_api_schema import ( create_service_callback_api_schema, update_service_callback_api_schema, ) service_callback_blueprint = Blueprint( "service_callback", __name__, url_prefix="/service/" ) register_errors(service_callback_blueprint) @service_callback_blueprint.route("/inbound-api", methods=["POST"]) def create_service_inbound_api(service_id): data = request.get_json() validate(data, create_service_callback_api_schema) data["service_id"] = service_id inbound_api = ServiceInboundApi(**data) try: save_service_inbound_api(inbound_api) except SQLAlchemyError as e: return handle_sql_error(e, "service_inbound_api") return jsonify(data=inbound_api.serialize()), 201 @service_callback_blueprint.route( "/inbound-api/", methods=["POST"] ) def update_service_inbound_api(service_id, inbound_api_id): data = request.get_json() validate(data, update_service_callback_api_schema) to_update = get_service_inbound_api(inbound_api_id, service_id) reset_service_inbound_api( service_inbound_api=to_update, updated_by_id=data["updated_by_id"], url=data.get("url", None), bearer_token=data.get("bearer_token", None), ) return jsonify(data=to_update.serialize()), 200 @service_callback_blueprint.route("/inbound-api/", methods=["GET"]) def fetch_service_inbound_api(service_id, inbound_api_id): inbound_api = get_service_inbound_api(inbound_api_id, service_id) return jsonify(data=inbound_api.serialize()), 200 @service_callback_blueprint.route( "/inbound-api/", methods=["DELETE"] ) def remove_service_inbound_api(service_id, inbound_api_id): inbound_api = get_service_inbound_api(inbound_api_id, service_id) if not inbound_api: error = "Service inbound API not found" raise InvalidRequest(error, status_code=404) delete_service_inbound_api(inbound_api) return "", 204 @service_callback_blueprint.route("/delivery-receipt-api", methods=["POST"]) def create_service_callback_api(service_id): data = request.get_json() validate(data, create_service_callback_api_schema) data["service_id"] = service_id data["callback_type"] = CallbackType.DELIVERY_STATUS callback_api = ServiceCallbackApi(**data) try: save_service_callback_api(callback_api) except SQLAlchemyError as e: return handle_sql_error(e, "service_callback_api") return jsonify(data=callback_api.serialize()), 201 @service_callback_blueprint.route( "/delivery-receipt-api/", methods=["POST"] ) def update_service_callback_api(service_id, callback_api_id): data = request.get_json() validate(data, update_service_callback_api_schema) to_update = get_service_callback_api(callback_api_id, service_id) reset_service_callback_api( service_callback_api=to_update, updated_by_id=data["updated_by_id"], url=data.get("url", None), bearer_token=data.get("bearer_token", None), ) return jsonify(data=to_update.serialize()), 200 @service_callback_blueprint.route( "/delivery-receipt-api/", methods=["GET"] ) def fetch_service_callback_api(service_id, callback_api_id): callback_api = get_service_callback_api(callback_api_id, service_id) return jsonify(data=callback_api.serialize()), 200 @service_callback_blueprint.route( "/delivery-receipt-api/", methods=["DELETE"] ) def remove_service_callback_api(service_id, callback_api_id): callback_api = get_service_callback_api(callback_api_id, service_id) if not callback_api: error = "Service delivery receipt callback API not found" raise InvalidRequest(error, status_code=404) delete_service_callback_api(callback_api) return "", 204 def handle_sql_error(e, table_name): if ( hasattr(e, "orig") and hasattr(e.orig, "pgerror") and e.orig.pgerror and ( 'duplicate key value violates unique constraint "ix_{}_service_id"'.format( table_name ) in e.orig.pgerror ) ): return ( jsonify( result="error", message={ "name": [ "You can only have one URL and bearer token for your service." ] }, ), 400, ) elif ( hasattr(e, "orig") and hasattr(e.orig, "pgerror") and e.orig.pgerror and ( 'insert or update on table "{0}" violates ' 'foreign key constraint "{0}_service_id_fkey"'.format(table_name) in e.orig.pgerror ) ): return jsonify(result="error", message="No result found"), 404 else: raise e