|
3 | 3 | import uuid |
4 | 4 | import time |
5 | 5 | import logging |
| 6 | +from contextlib import asynccontextmanager |
| 7 | +from typing import AsyncIterator |
6 | 8 | from fastapi import FastAPI, Request |
7 | 9 | from fastapi.middleware.cors import CORSMiddleware |
8 | 10 |
|
@@ -31,13 +33,44 @@ def create_app(settings=None) -> FastAPI: |
31 | 33 | if settings is None: |
32 | 34 | settings = get_settings() |
33 | 35 |
|
| 36 | + @asynccontextmanager |
| 37 | + async def lifespan(app: FastAPI) -> AsyncIterator[None]: |
| 38 | + # Configure logging using the app state before the app starts serving. |
| 39 | + app.state.logging_manager.configure_logging() |
| 40 | + |
| 41 | + # Disable uvicorn access logs to avoid duplication |
| 42 | + uvicorn_logger = logging.getLogger("uvicorn.access") |
| 43 | + uvicorn_logger.disabled = True |
| 44 | + |
| 45 | + logger = get_logger("api.startup") |
| 46 | + logger.info( |
| 47 | + "Application starting up", |
| 48 | + extra={ |
| 49 | + "log_level": settings.log_level, |
| 50 | + "log_format": settings.log_format, |
| 51 | + "api_version": settings.api_version, |
| 52 | + }, |
| 53 | + ) |
| 54 | + await create_tables() |
| 55 | + logger.info("Database tables created successfully") |
| 56 | + |
| 57 | + # Ensure initial admin user exists |
| 58 | + from .database import AsyncSessionLocal |
| 59 | + from .crud import ensure_initial_admin |
| 60 | + |
| 61 | + async with AsyncSessionLocal() as db: |
| 62 | + await ensure_initial_admin(db, settings.admin_initial_username) |
| 63 | + |
| 64 | + yield |
| 65 | + |
34 | 66 | # Create FastAPI instance |
35 | 67 | app = FastAPI( |
36 | 68 | title=settings.api_title, |
37 | 69 | version=settings.api_version, |
38 | 70 | docs_url="/api/docs", |
39 | 71 | redoc_url="/api/redoc", |
40 | 72 | openapi_url="/api/openapi.json", |
| 73 | + lifespan=lifespan, |
41 | 74 | ) |
42 | 75 |
|
43 | 76 | # Store dependencies in app state |
@@ -133,35 +166,6 @@ async def log_requests(request: Request, call_next): |
133 | 166 |
|
134 | 167 | return response |
135 | 168 |
|
136 | | - # Configure startup event |
137 | | - @app.on_event("startup") |
138 | | - async def startup_event(): |
139 | | - # Configure logging using the app state |
140 | | - app.state.logging_manager.configure_logging() |
141 | | - |
142 | | - # Disable uvicorn access logs to avoid duplication |
143 | | - uvicorn_logger = logging.getLogger("uvicorn.access") |
144 | | - uvicorn_logger.disabled = True |
145 | | - |
146 | | - logger = get_logger("api.startup") |
147 | | - logger.info( |
148 | | - "Application starting up", |
149 | | - extra={ |
150 | | - "log_level": settings.log_level, |
151 | | - "log_format": settings.log_format, |
152 | | - "api_version": settings.api_version, |
153 | | - }, |
154 | | - ) |
155 | | - await create_tables() |
156 | | - logger.info("Database tables created successfully") |
157 | | - |
158 | | - # Ensure initial admin user exists |
159 | | - from .database import AsyncSessionLocal |
160 | | - from .crud import ensure_initial_admin |
161 | | - |
162 | | - async with AsyncSessionLocal() as db: |
163 | | - await ensure_initial_admin(db, settings.admin_initial_username) |
164 | | - |
165 | 169 | # Include routers |
166 | 170 | app.include_router(health.router) |
167 | 171 | app.include_router(commits.router) |
|
0 commit comments