Files
kami_spider_monorepo/main.py
danial 6c768b6e7b feat(jd): 添加京东相关路由及苹果权益充值功能
- 新增jd模块基础路由,整合app_store和payment子路由
- 实现苹果权益充值接口,支持苹果、携程及沃尔玛多个渠道
- 实现卡号密码查询接口,支持不同类别订单查询
- 新增短信认证相关接口,实现短信验证码发送及短信登录
- 新增商品管理接口,支持SKU详情查询及账号类下单功能
- 新增订单管理接口,实现订单删除功能
- 实现支付相关接口,增加刷新支付参数功能
- 定义完整请求及响应数据模型,确保接口数据规范
- 编写AppStoreSpider类,封装苹果应用内订单处理逻辑
- 引入多种代理池及请求重试机制,增强接口稳定性
- 添加详细日志记录,便于请求追踪与错误排查
2025-11-03 19:35:39 +08:00

188 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 APIRouter, 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.apple.router import router as app_b_router
from apps.jd.router import router as jd_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)
router = APIRouter(prefix="/api")
router.include_router(jd_router())
app.include_router(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(),
)