from __future__ import annotations from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException, Request from fastapi.responses import JSONResponse from app.api.agent.tasks import router as task_router from app.api.demo.approval import router as demo_approval_router from app.api.demo.chat import router as demo_chat_router from app.api.demo.identity import router as demo_identity_router from app.api.demo.software_a import router as demo_software_a_router from app.api.edge.tasks import router as edge_router from app.api.web.demo import router as demo_web_router from app.core.config import ensure_runtime_directories, get_settings from app.core.time import format_now from app.db.base import Base from app.db.session import engine from app.db.session import SessionLocal from app.models.app_metadata import AppMetadata from app.models.approval import ApprovalRequest from app.models.audit_log import AuditLog from app.models.chat_message import ChatMessage from app.models.chat_session import ChatSession from app.models.edge_node import EdgeNode from app.models.edge_task import EdgeTask from app.models.task import Task from app.models.tool_call import ToolCall from app.services.metadata_service import MetadataService settings = get_settings() @asynccontextmanager async def lifespan(_: FastAPI): ensure_runtime_directories() Base.metadata.create_all(bind=engine) db = SessionLocal() try: MetadataService(db, settings.default_timezone).ensure_demo_metadata() finally: db.close() yield app = FastAPI( title="智能化部署 Agent Demo Backend", version="0.1.0", lifespan=lifespan, ) @app.exception_handler(HTTPException) async def http_exception_handler(_: Request, exc: HTTPException) -> JSONResponse: detail = exc.detail if isinstance(exc.detail, dict) else {"code": "INTERNAL_ERROR", "message": str(exc.detail)} return JSONResponse( status_code=exc.status_code, content={ "request_id": "req-exception", "success": False, "code": detail.get("code", "INTERNAL_ERROR"), "message": detail.get("message", "request failed"), "data": {}, "timestamp": format_now(settings.default_timezone), }, ) @app.get("/healthz") def healthz() -> dict[str, str]: return {"status": "ok"} app.include_router(task_router) app.include_router(demo_chat_router) app.include_router(demo_identity_router) app.include_router(demo_approval_router) app.include_router(demo_software_a_router) app.include_router(edge_router) app.include_router(demo_web_router)