| import time |
| from fastapi import FastAPI, Request |
| from fastapi.middleware.cors import CORSMiddleware |
| from app.routers import apm, readiness, supply_chain, upload, dashboard |
| from app.routers.activity import router as activity_router |
| from app.database import init_db, log_activity |
|
|
| |
| init_db() |
|
|
| app = FastAPI( |
| title="EVolve Intelligence", |
| description="AI platform for industrial EV asset performance and supply chain intelligence.", |
| version="1.0.0" |
| ) |
|
|
| import os |
| ALLOWED_ORIGINS = os.environ.get("ALLOWED_ORIGINS", "*").split(",") |
|
|
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=ALLOWED_ORIGINS, |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| |
| |
| SKIP_LOG_PREFIXES = ("/docs", "/openapi", "/redoc", "/favicon") |
|
|
| @app.middleware("http") |
| async def activity_logging_middleware(request: Request, call_next): |
| path = request.url.path |
| method = request.method |
|
|
| |
| if any(path.startswith(p) for p in SKIP_LOG_PREFIXES): |
| return await call_next(request) |
|
|
| start = time.time() |
| response = await call_next(request) |
| duration_ms = round((time.time() - start) * 1000) |
|
|
| |
| if path not in ("/", "/health"): |
| action = f"{method} {path} — {response.status_code} ({duration_ms}ms)" |
| log_activity( |
| action=action, |
| endpoint=path, |
| method=method, |
| status_code=response.status_code, |
| details={"duration_ms": duration_ms} |
| ) |
|
|
| return response |
|
|
| |
| app.include_router(apm.router) |
| app.include_router(readiness.router) |
| app.include_router(supply_chain.router) |
| app.include_router(upload.router) |
| app.include_router(dashboard.router) |
| app.include_router(activity_router) |
|
|
| @app.get("/") |
| def root(): |
| return { |
| "service": "EVolve Intelligence", |
| "modules": ["APM", "Fleet Readiness", "Supply Chain Risk"], |
| "docs": "/docs" |
| } |
|
|
| @app.get("/health") |
| def health(): |
| return {"status": "ok"} |
|
|