forked from cartsnitch/cartsnitch
2460a00d4e
- Refactor database.py to use init_db()/close_db() lifecycle - Add create_db_engine() with pool_size=10, max_overflow=20, pool_pre_ping=True - Replace cache.py stub with real Redis client using redis.asyncio - Implement init_redis()/close_redis() with graceful error handling - Replace no-op lifespan in main.py with proper startup/shutdown - Enhance health endpoint to check DB and Redis connectivity - Add tests for database, cache, and health endpoint lifecycle Co-Authored-By: Paperclip <noreply@paperclip.ing>
78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
"""FastAPI app factory for CartSnitch API Gateway."""
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import APIRouter, FastAPI
|
|
|
|
from cartsnitch_api.auth.routes import router as auth_router
|
|
from cartsnitch_api.cache import cache_client
|
|
from cartsnitch_api.database import dispose_engine
|
|
from cartsnitch_api.middleware.cors import add_cors_middleware
|
|
from cartsnitch_api.middleware.error_handler import add_error_handlers, add_error_monitor_middleware
|
|
from cartsnitch_api.middleware.rate_limit import add_rate_limit_middleware
|
|
from cartsnitch_api.middleware.audit import add_audit_middleware
|
|
from cartsnitch_api.routes.alerts import router as alerts_router
|
|
from cartsnitch_api.routes.coupons import router as coupons_router
|
|
from cartsnitch_api.routes.health import router as health_router
|
|
from cartsnitch_api.routes.prices import router as prices_router
|
|
from cartsnitch_api.routes.products import router as products_router
|
|
from cartsnitch_api.routes.public import router as public_router
|
|
from cartsnitch_api.routes.purchases import router as purchases_router
|
|
from cartsnitch_api.routes.scraping import router as scraping_router
|
|
from cartsnitch_api.routes.shopping import router as shopping_router
|
|
from cartsnitch_api.routes.stores import router as stores_router
|
|
from cartsnitch_api.routes.user import router as user_router
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
from cartsnitch_api.database import init_db, close_db
|
|
from cartsnitch_api.cache import init_redis, close_redis
|
|
|
|
await init_db()
|
|
await init_redis()
|
|
yield
|
|
await close_redis()
|
|
await close_db()
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
app = FastAPI(
|
|
title="CartSnitch API",
|
|
description="Grocery price tracking and shrinkflation detection API",
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# Middleware (order matters — outermost first)
|
|
add_cors_middleware(app)
|
|
add_error_monitor_middleware(app)
|
|
add_rate_limit_middleware(app)
|
|
add_audit_middleware(app)
|
|
|
|
# Exception handlers
|
|
add_error_handlers(app)
|
|
|
|
# Routers
|
|
app.include_router(health_router)
|
|
app.include_router(auth_router)
|
|
|
|
# Data endpoints mounted under /api/v1
|
|
v1_router = APIRouter(prefix="/api/v1")
|
|
v1_router.include_router(user_router)
|
|
v1_router.include_router(stores_router)
|
|
v1_router.include_router(purchases_router)
|
|
v1_router.include_router(products_router)
|
|
v1_router.include_router(prices_router)
|
|
v1_router.include_router(coupons_router)
|
|
v1_router.include_router(shopping_router)
|
|
v1_router.include_router(alerts_router)
|
|
v1_router.include_router(scraping_router)
|
|
v1_router.include_router(public_router)
|
|
app.include_router(v1_router)
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|