Files
MobilityOps/backend/app/main.py
T
NuklearRabbit c5b7e21f81 M6: implement ITWorx MCP Hub publication
Four read-only, service-token-protected MCP provider endpoints (operations summary, attention vehicles, vehicle details, knowledge search facade). Shared-secret auth reusing the M4 callback pattern. Service-request audit trail for every call. Extracted shared operations-summary logic out of the dashboard router to avoid duplicating retrieval logic. 66 backend tests passing, ruff clean. Verified all four endpoints and audit trail directly via curl against the live stack (no live MCP Hub instance available in this environment).
2026-08-01 23:05:04 +02:00

91 lines
2.4 KiB
Python

import uuid
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from app.api.routers import (
audit,
bookings,
dashboard,
data_quality,
demo,
integrations,
knowledge,
mcp_integrations,
vehicles,
workflows,
)
from app.core.config import get_settings
from app.core.errors import AppError, error_body
from app.services.dispatcher import start_background_dispatcher, stop_background_dispatcher
settings = get_settings()
@asynccontextmanager
async def lifespan(_app: FastAPI):
start_background_dispatcher()
yield
stop_background_dispatcher()
app = FastAPI(title="MobilityOps API", version="0.1.0", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=[o.strip() for o in settings.cors_allow_origins.split(",")],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.exception_handler(AppError)
def handle_app_error(_request: Request, exc: AppError) -> JSONResponse:
return JSONResponse(
status_code=exc.status_code,
content=error_body(exc.code, exc.message, exc.correlation_id, exc.details),
)
@app.exception_handler(HTTPException)
def handle_http_exception(_request: Request, exc: HTTPException) -> JSONResponse:
return JSONResponse(
status_code=exc.status_code,
content=error_body(
code=str(exc.status_code),
message=str(exc.detail),
correlation_id=str(uuid.uuid4()),
details={},
),
)
@app.get("/health")
def health() -> dict[str, str]:
return {"status": "ok", "service": "mobilityops-api"}
@app.get("/api/v1/system/status")
def system_status() -> dict[str, object]:
return {
"service": "mobilityops-api",
"environment": settings.mobilityops_env,
"demo_mode": settings.mobilityops_demo_mode,
"knowledge_provider": settings.knowledge_provider,
}
app.include_router(demo.router)
app.include_router(dashboard.router)
app.include_router(vehicles.router)
app.include_router(bookings.router)
app.include_router(audit.router)
app.include_router(data_quality.router)
app.include_router(workflows.router)
app.include_router(integrations.router)
app.include_router(knowledge.router)
app.include_router(mcp_integrations.router)