- 添加 .env.example 环境变量配置示例 - 添加 .gitignore 忽略文件配置 - 添加 core/config.py 配置管理模块 - 添加 deployments/k8s/configmap.yaml Kubernetes 配置 - 添加 core/database.py 数据库连接管理模块 - 添加 core/dependencies.py 全局依赖模块 - 添加 DEPENDENCIES_UPDATED.md 依赖更新记录 - 添加 deployments/k8s/deployment.yaml Kubernetes 部署配置- 添加 deployments/swarm/docker-compose.swarm.yml Docker Swarm 部署配置 - 添加 deployments/docker/docker-compose.yml Docker 部署配置 - 添加 deployments/docker/Dockerfile 应用镜像构建文件 - 添加 middleware/error_handler.py 全局异常处理中间件
185 lines
5.1 KiB
Python
185 lines
5.1 KiB
Python
"""
|
|
Main FastAPI application entry point.
|
|
Bootstraps the application with middleware, routers, and lifecycle handlers.
|
|
"""
|
|
|
|
from contextlib import asynccontextmanager
|
|
from fastapi import FastAPI
|
|
from fastapi.responses import ORJSONResponse
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from core.config import settings
|
|
from core.database import create_db_and_tables, close_database_connection
|
|
from core.redis import init_redis, close_redis_connection
|
|
from core.responses import ERROR_RESPONSES
|
|
from observability.tracing import init_tracing, instrument_app, shutdown_tracing
|
|
from observability.logging import setup_logging, get_logger
|
|
from middleware.trace_context import TraceContextMiddleware
|
|
from middleware.logging import RequestLoggingMiddleware
|
|
from middleware.error_handler import register_exception_handlers
|
|
from apps.app_a.router import router as app_a_router
|
|
from apps.app_b.router import router as app_b_router
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""
|
|
Application lifespan manager.
|
|
|
|
Handles startup and shutdown events.
|
|
"""
|
|
# Startup
|
|
logger.info("Starting application...")
|
|
|
|
# Setup logging
|
|
setup_logging()
|
|
logger.info(f"Logging configured: level={settings.log_level}")
|
|
|
|
# Initialize OpenTelemetry
|
|
if settings.otel_enabled:
|
|
init_tracing()
|
|
instrument_app(app)
|
|
logger.info(f"OpenTelemetry initialized: endpoint={settings.otel_exporter_endpoint}")
|
|
|
|
# Initialize Redis
|
|
await init_redis()
|
|
logger.info(f"Redis initialized: {settings.redis_host}:{settings.redis_port}")
|
|
|
|
# Create database tables (development only)
|
|
if settings.is_development:
|
|
await create_db_and_tables()
|
|
logger.info("Database tables created")
|
|
|
|
logger.info(f"Application started: environment={settings.environment}")
|
|
|
|
yield
|
|
|
|
# Shutdown
|
|
logger.info("Shutting down application...")
|
|
|
|
# Close Redis connection
|
|
await close_redis_connection()
|
|
logger.info("Redis connection closed")
|
|
|
|
# Close database connection
|
|
await close_database_connection()
|
|
logger.info("Database connection closed")
|
|
|
|
# Shutdown OpenTelemetry
|
|
if settings.otel_enabled:
|
|
await shutdown_tracing()
|
|
logger.info("OpenTelemetry shutdown")
|
|
|
|
logger.info("Application shutdown complete")
|
|
|
|
|
|
# Create FastAPI application
|
|
app = FastAPI(
|
|
title=settings.app_name,
|
|
description="A stateless, production-ready FastAPI web service platform",
|
|
version="0.1.0",
|
|
debug=settings.debug,
|
|
lifespan=lifespan,
|
|
docs_url="/docs",
|
|
redoc_url="/redoc",
|
|
openapi_url="/openapi.json",
|
|
default_response_class=ORJSONResponse, # Use orjson for better performance
|
|
)
|
|
|
|
# Add CORS middleware
|
|
if settings.cors_enabled:
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_allow_origins,
|
|
allow_credentials=settings.cors_allow_credentials,
|
|
allow_methods=settings.cors_allow_methods,
|
|
allow_headers=settings.cors_allow_headers,
|
|
)
|
|
|
|
# Add custom middleware (order matters: last added = first executed)
|
|
app.add_middleware(RequestLoggingMiddleware)
|
|
app.add_middleware(TraceContextMiddleware)
|
|
|
|
# Register exception handlers
|
|
register_exception_handlers(app)
|
|
|
|
# Include application routers
|
|
app.include_router(app_a_router)
|
|
app.include_router(app_b_router)
|
|
|
|
|
|
# Health check endpoint
|
|
@app.get(
|
|
"/health",
|
|
tags=["Health"],
|
|
summary="Health check",
|
|
description="Check the health status of the application and its dependencies",
|
|
responses={
|
|
200: {"description": "Service is healthy"},
|
|
500: ERROR_RESPONSES[500],
|
|
503: ERROR_RESPONSES[503],
|
|
}
|
|
)
|
|
async def health_check():
|
|
"""
|
|
Health check endpoint.
|
|
|
|
Returns health status of the application and its components.
|
|
"""
|
|
from core.database import check_database_connection
|
|
from core.redis import check_redis_connection
|
|
|
|
# Check database
|
|
db_healthy = await check_database_connection()
|
|
|
|
# Check Redis
|
|
redis_healthy = await check_redis_connection()
|
|
|
|
# Overall health
|
|
healthy = db_healthy and redis_healthy
|
|
|
|
return {
|
|
"status": "healthy" if healthy else "unhealthy",
|
|
"components": {
|
|
"api": "healthy",
|
|
"database": "healthy" if db_healthy else "unhealthy",
|
|
"redis": "healthy" if redis_healthy else "unhealthy",
|
|
},
|
|
"environment": settings.environment,
|
|
"version": "0.1.0",
|
|
}
|
|
|
|
|
|
# Root endpoint
|
|
@app.get(
|
|
"/",
|
|
tags=["Root"],
|
|
summary="Root endpoint",
|
|
description="Get API information",
|
|
responses={
|
|
200: {"description": "API information retrieved successfully"},
|
|
}
|
|
)
|
|
async def root():
|
|
"""Root endpoint with API information."""
|
|
return {
|
|
"name": settings.app_name,
|
|
"version": "0.1.0",
|
|
"environment": settings.environment,
|
|
"docs": "/docs",
|
|
"health": "/health",
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
|
|
uvicorn.run(
|
|
"main:app",
|
|
host=settings.host,
|
|
port=settings.port,
|
|
reload=settings.debug,
|
|
log_level=settings.log_level.lower(),
|
|
)
|