Nanny7's picture
Phase 4: Infrastructure, Docker, Kubernetes, Chatbot with Qwen API
e566277
"""
FastAPI application main entry point.
Configures the FastAPI app with CORS middleware, routes, and middleware.
"""
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from src.core.config import settings
from src.core.database import DatabaseManager, init_db
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
"""
Lifespan context manager for FastAPI app.
Handles startup and shutdown events.
"""
# Scheduler instance
scheduler = None
# Startup
print(f"Starting Todo App API")
print(f"Environment: {settings.env}")
print(f"Database: {settings.database_url.split('@')[-1]}")
# Initialize database (create tables if not exists)
# In production, use Alembic migrations instead
if settings.is_development:
init_db()
print("Database initialized")
# Start reminder scheduler if Gmail configured
if settings.gmail_email and settings.gmail_app_password:
try:
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from src.services.reminder_service import check_and_send_reminders
from src.core.database import get_session
scheduler = AsyncIOScheduler()
# Add job to check reminders every hour
def run_reminder_check():
"""Wrapper to get fresh session for each check."""
session = next(get_session())
try:
check_and_send_reminders(session)
finally:
session.close()
scheduler.add_job(
run_reminder_check,
'interval',
hours=1,
id='reminder_checker',
name='Check and send task reminders'
)
scheduler.start()
print("✅ Reminder scheduler started (runs every hour)")
except Exception as e:
print(f"⚠️ Failed to start reminder scheduler: {e}")
else:
print("⚠️ Reminder scheduler disabled (Gmail not configured)")
yield
# Shutdown
if scheduler:
scheduler.shutdown()
print("Reminder scheduler stopped")
print("Shutting down Todo App API")
# Create FastAPI app
app = FastAPI(
title='Todo App API',
description='Premium Todo SaaS Application API',
version='0.1.0',
docs_url='/docs',
redoc_url='/redoc',
lifespan=lifespan,
)
# Configure CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins,
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
# Global exception handler
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
"""Handle all unhandled exceptions."""
print(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={
'detail': 'Internal server error',
'message': str(exc) if settings.is_development else 'An error occurred',
},
)
# Health check endpoint
@app.get('/health', tags=['Health'])
async def health_check():
"""
Health check endpoint.
Returns API status and database connection status.
"""
db_connected = DatabaseManager.check_connection()
return {
'status': 'healthy',
'api': 'Todo App API',
'version': '0.1.0',
'environment': settings.env,
'database': 'connected' if db_connected else 'disconnected',
}
# Root endpoint
@app.get('/', tags=['Root'])
async def root():
"""
Root endpoint with API information.
"""
return {
'message': 'Welcome to Todo App API',
'version': '0.1.0',
'docs': '/docs',
'health': '/health',
}
# Include routers
from src.api import auth, todos, users, ai, chat
app.include_router(auth.router, prefix='/api/auth', tags=['Authentication'])
app.include_router(todos.router, prefix='/api/todos', tags=['Todos'])
app.include_router(users.router, prefix='/api/users', tags=['Users'])
app.include_router(ai.router, prefix='/api/ai', tags=['AI'])
# T010: Added AI chat router for dashboard integration with /api/ai-chat prefix
app.include_router(chat.router, tags=['AI Chat']) # Router has /api/ai-chat prefix defined in chat.py
if __name__ == '__main__':
import uvicorn
uvicorn.run(
'src.main:app',
host='0.0.0.0',
port=settings.port,
reload=settings.is_development,
)