"""Application. The application is a `fastapi` application. Includes request routing configs, exception handling and Sentry configs. """ from typing import Any, Dict, Union import sentry_sdk from audience_common.logger.asgi.middleware import RequestLoggerMiddleware from fastapi import FastAPI, HTTPException from fastapi.datastructures import Default from fastapi.middleware import Middleware from fastapi.responses import JSONResponse from jwtauth.asgi.middleware import JWTAuthenticationMiddleware from jwtauth.utils import jwt_auth_enabled_for_env, jwt_auth_from_environment from owscontext.context.asgi.middleware import ( CorrelationIdMiddleware, RequestContextMiddleware, ) from pdp import config from pdp.fastapi import error_handlers from pdp.fastapi.datasources import datasources_lifespan from pdp.fastapi.routers import identity, infra, temp from pdp.fastapi.schemas import identity as identity_schema from pdp.utils.sentry import sentry_ignore_loggers class SentryInitError(Exception): pass app = FastAPI( debug=config.APP_DEBUG, title=config.SERVICE_NAME, version=config.SERVICE_VERSION, default_response_class=Default(JSONResponse), description="Policy Decision Point (PDP) Service", lifespan=datasources_lifespan, middleware=[ Middleware(CorrelationIdMiddleware), Middleware(RequestContextMiddleware), Middleware( RequestLoggerMiddleware, exclude_paths=["/hello/", "/redoc", "/docs", "/openapi.json"], ), Middleware( JWTAuthenticationMiddleware, environment=config.ENVIRONMENT, enabled=jwt_auth_enabled_for_env(config.ENVIRONMENT), exclude_paths=["/hello/", "/redoc", "/docs", "/openapi.json"], auth=jwt_auth_from_environment(config.ENVIRONMENT), ), ], ) error_responses: Dict[Union[int, str], Dict[str, Any]] = { 400: {"description": "Bad request", "model": identity_schema.OwsError}, 401: {"description": "Unauthenticated request", "model": identity_schema.OwsError}, 403: {"description": "Forbidden", "model": identity_schema.OwsError}, 500: {"description": "Internal server error", "model": identity_schema.OwsError}, } app.include_router(infra.router) app.include_router(identity.router, responses=error_responses) app.include_router(temp.router) # Register exception handlers app.add_exception_handler(Exception, error_handlers.default_error_handler) app.add_exception_handler( HTTPException, error_handlers.http_error_handler, # type: ignore[arg-type] ) if config.ENVIRONMENT in [config.PROD_ENVIRONMENT, config.QA_ENVIRONMENT]: if not config.SENTRY: raise SentryInitError(f"Sentry is not configured in {config.ENVIRONMENT}") sentry_sdk.init(dsn=config.SENTRY, before_send=sentry_ignore_loggers)