Files
NyaHome/src/nyahome/server.py
T

76 lines
2.4 KiB
Python

import asyncio
import json
import logging
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Any, AsyncGenerator
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from nyahome.router import admin_router, aii_router, chatroom_router, file_router, webui_router
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncGenerator[None, Any]:
# 在生命周期函数内先加载环境变量,再局部导入 nyahome 核心模块
logger.info("🚀 服务启动中...")
from nyahome.config import config_manager
from nyahome.core.otp_store import email_otp_memory_store
from nyahome.core.send_email import email_sender_queue
from nyahome.core.task import init_admin_user
from nyahome.database import create_db
create_db()
await asyncio.gather(init_admin_user(), config_manager.async_load_config())
email_sender_queue.start()
email_otp_memory_store.start()
logger.info("🌸 server 启动完成。")
try:
yield
except Exception as e:
logger.error(f"捕获到无法处理的异常,NyaHome 即将结束 - {e}")
finally:
logger.info("🌕 服务关闭中...")
app = FastAPI(title="🌸 NyaHome ~", lifespan=lifespan)
app.include_router(webui_router)
app.include_router(chatroom_router, prefix="/api")
app.include_router(admin_router, prefix="/api")
app.include_router(file_router, prefix="/api")
app.include_router(aii_router, prefix="/api")
app.mount("/nyahome", StaticFiles(directory=Path.cwd() / "public"), name="public")
app.mount("/download", StaticFiles(directory=Path.cwd() / ".nyahome/contents"), name="upload")
# noinspection PyTypeChecker
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
def save_openapi_json(save_path: str | Path) -> None:
try:
from docstring_parser import DocstringStyle
except ImportError as e:
raise RuntimeError("开发依赖 docstring_parser 不存在,请使用 git clone 方式克隆 NyaHome。") from e
from nyahome.cli.openapi_docstring import enrich_openapi_from_docstrings
# 增强 openapi docstring 参数文档提取
enrich_openapi_from_docstrings(app, docstring_style=DocstringStyle.GOOGLE)
with open(save_path, "w") as f:
json.dump(app.openapi(), f, indent=2)