SuZeAI
feat: add token usage tracking for AI recommendations and subscription management
ff5991d
Raw
History Blame Contribute Delete
3.4 kB
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from app.core.config import settings
from app.api.router import api_router
from app.core.database import Base, engine
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
# Initialize database tables
try:
Base.metadata.create_all(bind=engine)
logging.info("Database tables initialized successfully.")
# Proactively ensure chest_cm, waist_cm, hips_cm columns exist in body_profiles
from sqlalchemy import text
with engine.begin() as conn:
for col in ["chest_cm", "waist_cm", "hips_cm"]:
try:
conn.execute(text(f"ALTER TABLE body_profiles ADD COLUMN IF NOT EXISTS {col} REAL;"))
except Exception as e:
# Fallback for SQLite or older databases where IF NOT EXISTS might fail
try:
conn.execute(text(f"ALTER TABLE body_profiles ADD COLUMN {col} REAL;"))
except Exception:
pass
# Ensure chat_messages has conversation_id (added after the table first shipped)
try:
conn.execute(text("ALTER TABLE chat_messages ADD COLUMN IF NOT EXISTS conversation_id UUID;"))
except Exception:
pass
# Ensure chat_messages has tokens_used (added after the table first shipped)
try:
conn.execute(text("ALTER TABLE chat_messages ADD COLUMN IF NOT EXISTS tokens_used INTEGER NOT NULL DEFAULT 0;"))
except Exception:
pass
# Ensure users has plan/premium_renews_at (added after the table first shipped)
try:
conn.execute(text("ALTER TABLE users ADD COLUMN IF NOT EXISTS plan VARCHAR(20) NOT NULL DEFAULT 'free';"))
except Exception:
pass
try:
conn.execute(text("ALTER TABLE users ADD COLUMN IF NOT EXISTS premium_renews_at TIMESTAMPTZ;"))
except Exception:
pass
except Exception as e:
logging.error(f"Error initializing database: {e}")
app = FastAPI(
title=settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json"
)
# CORS Middleware configurations (Security Guidelines)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.BACKEND_CORS_ORIGINS,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["*"],
)
from fastapi.staticfiles import StaticFiles
import os
# Register routers
app.include_router(api_router, prefix=settings.API_V1_STR)
# Mount local storage folder as static files if mode is local
if settings.STORAGE_MODE == "local":
os.makedirs(settings.UPLOAD_DIR, exist_ok=True)
app.mount("/static", StaticFiles(directory=settings.UPLOAD_DIR), name="static")
# Global Exception Handler to avoid leaking internals (Security Guidelines)
@app.exception_handler(Exception)
def global_exception_handler(request: Request, exc: Exception):
logging.error(f"Internal error occurred on {request.url.path}: {exc}", exc_info=True)
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={"detail": "Có lỗi hệ thống xảy ra. Vui lòng thử lại sau."}
)
@app.get("/health", tags=["healthcheck"])
def health_check():
return {"status": "healthy"}