#!/usr/bin/env python3 import uvicorn from contextlib import asynccontextmanager from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi_cache import FastAPICache from opentelemetry import trace from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor from opentelemetry.sdk.resources import Resource, SERVICE_NAME from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from db import db from dependencies import idfm_interface, redis_backend, settings from routers import line, stop @asynccontextmanager async def lifespan(app: FastAPI): FastAPICache.init(redis_backend, prefix="api", enable=settings.cache.enable) await db.connect(settings.db, settings.clear_static_data) if settings.clear_static_data: await idfm_interface.startup() yield await db.disconnect() app = FastAPI(lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["http://carrramba.adrien.run", "https://carrramba.adrien.run"], allow_credentials=True, allow_methods=["OPTIONS", "GET"], allow_headers=["*"], ) # The cache-control header entry is not managed properly by fastapi-cache: # For now, a request with a cache-control set to no-cache # is interpreted as disabling the use of the server cache. # Cf. Improve Cache-Control header parsing and handling # https://github.com/long2ice/fastapi-cache/issues/144 workaround @app.middleware("http") async def fastapi_cache_issue_144_workaround(request: Request, call_next): entries = request.headers.__dict__["_list"] new_entries = [ entry for entry in entries if entry[0].decode().lower() != "cache-control" ] request.headers.__dict__["_list"] = new_entries return await call_next(request) app.include_router(line.router) app.include_router(stop.router) if settings.tracing.enable: FastAPIInstrumentor.instrument_app(app) trace.set_tracer_provider( TracerProvider(resource=Resource.create({SERVICE_NAME: settings.app_name})) ) trace.get_tracer_provider().add_span_processor( BatchSpanProcessor(OTLPSpanExporter()) ) tracer = trace.get_tracer(settings.app_name) if __name__ == "__main__": http_settings = settings.http config = uvicorn.Config( app=app, host=http_settings.host, port=http_settings.port, ssl_certfile=http_settings.cert, proxy_headers=True, ) server = uvicorn.Server(config) server.run()