Files
openrouter-watcher/src/openrouter_monitor/main.py
Luca Sacchi Ricciardi a605b7f29e feat(frontend): T47-T54 implement web interface routes
- Add web router with all frontend pages
- Login/Register pages with form validation
- Dashboard with stats cards and Chart.js
- API Keys management with CRUD operations
- Stats page with filtering and pagination
- API Tokens management with generation/revocation
- User profile with password change and account deletion
- Add shared templates_config.py to avoid circular imports
- Add CSRF protection middleware
- Add get_current_user_optional dependency for web routes

All routes verified working:
- GET /login, POST /login
- GET /register, POST /register
- POST /logout
- GET /dashboard
- GET /keys, POST /keys, DELETE /keys/{id}
- GET /stats
- GET /tokens, POST /tokens, DELETE /tokens/{id}
- GET /profile, POST /profile/password, DELETE /profile
2026-04-07 18:15:26 +02:00

86 lines
2.4 KiB
Python

"""FastAPI main application.
Main application entry point for OpenRouter API Key Monitor.
"""
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from openrouter_monitor.config import get_settings
from openrouter_monitor.templates_config import templates
from openrouter_monitor.middleware.csrf import CSRFMiddleware
from openrouter_monitor.routers import api_keys
from openrouter_monitor.routers import auth
from openrouter_monitor.routers import public_api
from openrouter_monitor.routers import stats
from openrouter_monitor.routers import tokens
from openrouter_monitor.routers import web
from openrouter_monitor.tasks.scheduler import init_scheduler, shutdown_scheduler
settings = get_settings()
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Application lifespan manager.
Handles startup and shutdown events including
scheduler initialization and cleanup.
"""
# Startup
init_scheduler()
yield
# Shutdown
shutdown_scheduler()
# Get project root directory
PROJECT_ROOT = Path(__file__).parent.parent.parent
# Create FastAPI app
app = FastAPI(
title="OpenRouter API Key Monitor",
description="Monitor and manage OpenRouter API keys",
version="1.0.0",
debug=settings.debug,
lifespan=lifespan,
)
# Mount static files (before CSRF middleware to allow access without token)
app.mount("/static", StaticFiles(directory=str(PROJECT_ROOT / "static")), name="static")
# CSRF protection middleware
app.add_middleware(CSRFMiddleware)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(auth.router, prefix="/api/auth", tags=["authentication"])
app.include_router(api_keys.router, prefix="/api/keys", tags=["api-keys"])
app.include_router(tokens.router)
app.include_router(stats.router)
app.include_router(public_api.router)
app.include_router(web.router)
@app.get("/")
async def root():
"""Root endpoint."""
return {"message": "OpenRouter API Key Monitor API", "version": "1.0.0"}
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "healthy"}