-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy path__init__.py
More file actions
87 lines (74 loc) · 2.73 KB
/
__init__.py
File metadata and controls
87 lines (74 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import logging
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from starlette.responses import JSONResponse
from common import AppConfig, application_init
from common.di_container import Container
from common.errors import ApplicationError
from common.telemetry import instrument_third_party
from http_app import context
from http_app.routes import init_routes
# These instrumentors patch and wrap libraries, we want
# to execute them ASAP
instrument_third_party()
def create_app(
test_config: AppConfig | None = None,
test_di_container: Container | None = None,
) -> FastAPI:
app_config = test_config or AppConfig()
"""
The config is submitted here at runtime, this means
that we cannot declare a function to be used with
FastAPI dependency injection system because Depends
is evaluated before this function is called.
A context variable will achieve the same purpose.
"""
context.app_config.set(app_config)
ref = application_init(app_config, test_di_container)
ref.di_container.wire(packages=["http_app"])
app = FastAPI(
debug=app_config.DEBUG,
title=app_config.APP_NAME,
)
init_exception_handlers(app)
if app_config.CORS_ORIGINS:
app.add_middleware(
CORSMiddleware,
allow_origins=app_config.CORS_ORIGINS,
allow_credentials=True,
allow_methods=app_config.CORS_METHODS,
allow_headers=app_config.CORS_HEADERS,
)
init_routes(app)
FastAPIInstrumentor.instrument_app(app)
return app
def init_exception_handlers(app: FastAPI) -> None:
# This is a catch-all middleware for unhandled exceptions
# other Exception handlers should be initialised using
# the @app.exception_handler decorator
# https://fastapi.tiangolo.com/tutorial/handling-errors/#install-custom-exception-handlers
@app.middleware("http")
async def add_exception_middleware(request: Request, call_next):
try:
return await call_next(request)
except ApplicationError as e:
logging.exception(
e.internal_message,
extra={
"code": e.code,
"metadata": e.metadata,
},
)
return JSONResponse(
{
"error": {
"message": e.public_message,
"code": e.code,
}
},
status_code=500,
)
except Exception as e:
logging.exception(e)
return JSONResponse({"error": "Internal server error"}, status_code=500)