imetting/backend/app/app_factory.py

115 lines
4.0 KiB
Python

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.staticfiles import StaticFiles
import contextlib
from app.api.endpoints import (
admin,
admin_dashboard,
admin_settings,
audio,
auth,
client_downloads,
dict_data,
external_apps,
hot_words,
knowledge_base,
meetings,
prompts,
tags,
tasks,
terminals,
users,
voiceprint,
)
from app.core.config import UPLOAD_DIR
from app.core.middleware import MCPPathNormalizeMiddleware, TerminalCheckMiddleware
from app.mcp import create_mcp_http_app, get_mcp_session_manager
from app.services.system_config_service import SystemConfigService
def create_app() -> FastAPI:
app = FastAPI(
title="iMeeting API",
description="iMeeting API说明",
version="1.1.0",
docs_url=None,
redoc_url=None,
)
app.add_middleware(MCPPathNormalizeMiddleware)
app.add_middleware(TerminalCheckMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if UPLOAD_DIR.exists():
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
mcp_asgi_app = create_mcp_http_app()
mcp_session_manager = get_mcp_session_manager()
if mcp_asgi_app is not None:
app.mount("/mcp", mcp_asgi_app, name="mcp")
app.include_router(auth.router, prefix="/api", tags=["Authentication"])
app.include_router(users.router, prefix="/api", tags=["Users"])
app.include_router(meetings.router, prefix="/api", tags=["Meetings"])
app.include_router(tags.router, prefix="/api", tags=["Tags"])
app.include_router(admin.router, prefix="/api", tags=["Admin"])
app.include_router(admin_dashboard.router, prefix="/api", tags=["AdminDashboard"])
app.include_router(admin_settings.router, prefix="/api", tags=["AdminSettings"])
app.include_router(tasks.router, prefix="/api", tags=["Tasks"])
app.include_router(prompts.router, prefix="/api", tags=["Prompts"])
app.include_router(knowledge_base.router, prefix="/api", tags=["KnowledgeBase"])
app.include_router(client_downloads.router, prefix="/api", tags=["ClientDownloads"])
app.include_router(external_apps.router, prefix="/api", tags=["ExternalApps"])
app.include_router(dict_data.router, prefix="/api", tags=["DictData"])
app.include_router(voiceprint.router, prefix="/api", tags=["Voiceprint"])
app.include_router(audio.router, prefix="/api", tags=["Audio"])
app.include_router(hot_words.router, prefix="/api", tags=["HotWords"])
app.include_router(terminals.router, prefix="/api", tags=["Terminals"])
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css",
)
@app.get("/")
def read_root():
return {"message": "Welcome to iMeeting API"}
@app.get("/health")
def health_check():
return {
"status": "healthy",
"service": "iMeeting API",
"version": "1.1.0",
}
if mcp_session_manager is not None:
@app.on_event("startup")
async def startup_mcp_session_manager():
exit_stack = contextlib.AsyncExitStack()
await exit_stack.enter_async_context(mcp_session_manager.run())
app.state.mcp_exit_stack = exit_stack
@app.on_event("shutdown")
async def shutdown_mcp_session_manager():
exit_stack = getattr(app.state, "mcp_exit_stack", None)
if exit_stack is not None:
await exit_stack.aclose()
SystemConfigService.ensure_builtin_parameters()
return app