def before_request(): if request.method == "OPTIONS": return "", 200 if "/static/" in request.path: return try: call = create_api_call(request) content, content_type = ServiceRepo.handle_call(call) headers = {} if call.result.filename: headers[ "Content-Disposition"] = f"attachment; filename={call.result.filename}" if call.result.headers: headers.update(call.result.headers) response = Response(content, mimetype=content_type, status=call.result.code, headers=headers) if call.result.cookies: for key, value in call.result.cookies.items(): if value is None: response.set_cookie(key, "", expires=0) else: response.set_cookie(key, value, **config.get("apiserver.auth.cookies")) return response except Exception as ex: log.exception(f"Failed processing request {request.url}: {ex}") return f"Failed processing request {request.url}", 500
def create_api_call(req): call = None try: # Parse the request path endpoint_version, endpoint_name = ServiceRepo.parse_endpoint_path(req.path) # Resolve authorization: if cookies contain an authorization token, use it as a starting point. # in any case, request headers always take precedence. auth_cookie = req.cookies.get( config.get("apiserver.auth.session_auth_cookie_name") ) headers = ( {} if not auth_cookie else {"Authorization": f"{AuthType.bearer_token} {auth_cookie}"} ) headers.update( list(req.headers.items()) ) # add (possibly override with) the headers # Construct call instance call = APICall( endpoint_name=endpoint_name, remote_addr=req.remote_addr, endpoint_version=endpoint_version, headers=headers, files=req.files, ) # Update call data from request with TimingContext("preprocess", "update_call_data"): update_call_data(call, req) except PathParsingError as ex: call = _call_or_empty_with_error(call, req, ex.args[0], 400) call.log_api = False except BadRequest as ex: call = _call_or_empty_with_error(call, req, ex.description, 400) except BaseError as ex: call = _call_or_empty_with_error(call, req, ex.msg, ex.code, ex.subcode) except Exception as ex: log.exception("Error creating call") call = _call_or_empty_with_error( call, req, ex.args[0] if ex.args else type(ex).__name__, 500 ) return call
def before_request(): if request.method == "OPTIONS": return "", 200 if "/static/" in request.path: return try: call = create_api_call(request) content, content_type = ServiceRepo.handle_call(call) headers = None if call.result.filename: headers = { "Content-Disposition": f"attachment; filename={call.result.filename}" } return Response( content, mimetype=content_type, status=call.result.code, headers=headers ) except Exception as ex: log.exception(f"Failed processing request {request.url}: {ex}") return f"Failed processing request {request.url}", 500
CORS(app, **config.get("apiserver.cors")) Compress(app) log = config.logger(__file__) log.info("################ API Server initializing #####################") app.config["SECRET_KEY"] = config.get("secure.http.session_secret.apiserver") app.config["JSONIFY_PRETTYPRINT_REGULAR"] = config.get("apiserver.pretty_json") database.initialize() init_es_data() init_mongo_data() ServiceRepo.load("services") log.info(f"Exposed Services: {' '.join(ServiceRepo.endpoint_names())}") @app.before_first_request def before_app_first_request(): pass @app.before_request def before_request(): if request.method == "OPTIONS": return "", 200 if "/static/" in request.path: return
def get_endpoints(call: APICall): call.result.data = ServiceRepo.endpoints_summary()