main.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import os
  2. import time
  3. import asyncio
  4. import logging
  5. from fastapi import FastAPI, Request
  6. from app.api import health, recommend, chat, analyze, tongue, adapter, report_parse, meal, logs, audio, innate_portrait, self_check, knowledge_base, portrait, article_quiz, indicator_classify
  7. from app import monitoring
  8. from src.app import router as questionnaire_router
  9. from app.middleware import RequestLogMiddleware
  10. logger = logging.getLogger(__name__)
  11. app = FastAPI(title="cfc-langgraph", version="0.3.0")
  12. # 注册请求日志中间件(纯 ASGI,避免 BaseHTTPMiddleware 消费 body 导致单 worker 死锁)
  13. app.add_middleware(RequestLogMiddleware)
  14. app.include_router(health.router)
  15. app.include_router(recommend.router)
  16. app.include_router(chat.router)
  17. app.include_router(analyze.router)
  18. app.include_router(tongue.router)
  19. app.include_router(adapter.router)
  20. app.include_router(monitoring.router)
  21. app.include_router(questionnaire_router)
  22. app.include_router(report_parse.router)
  23. app.include_router(meal.router)
  24. app.include_router(audio.router)
  25. app.include_router(logs.router)
  26. app.include_router(innate_portrait.router)
  27. app.include_router(self_check.router)
  28. app.include_router(self_check.router)
  29. app.include_router(knowledge_base.router)
  30. app.include_router(portrait.router)
  31. app.include_router(article_quiz.router)
  32. app.include_router(indicator_classify.router)
  33. @app.on_event("startup")
  34. async def startup():
  35. from app.config import settings
  36. from app.log_config import setup_logging
  37. json_logs = os.getenv("JSON_LOGS", "false").lower() == "true"
  38. setup_logging(level=settings.log_level, json_format=json_logs)
  39. # 初始化 faster-whisper STT 模型
  40. from app.audio.transcriber import init_model
  41. init_model()
  42. if os.getenv("LANGCHAIN_TRACING_V2", "").lower() == "true":
  43. logger.info(
  44. "LangSmith 已启用: project=%s, api_key=%s...",
  45. settings.langchain_project,
  46. settings.langchain_api_key[:8] if settings.langchain_api_key else "none",
  47. )
  48. from app.rag.retriever import RagRetriever
  49. retriever = RagRetriever()
  50. await retriever.initialize()
  51. # 初始化 LangGraph checkpointer(必须在运行中的事件循环内创建 AsyncSqliteSaver)
  52. from app.checkpointer import init_checkpointer
  53. await init_checkpointer()
  54. async def schedule_kb_sync():
  55. # 首次同步延迟 120s,让 healthcheck 先通过,避免 worker 刚启动就被阻塞
  56. await asyncio.sleep(120)
  57. while True:
  58. try:
  59. from app.tasks.knowledge_sync import sync_knowledge_base
  60. await sync_knowledge_base()
  61. except Exception as e:
  62. logger.warning("知识库同步失败: %s", e)
  63. await asyncio.sleep(3600)
  64. asyncio.create_task(schedule_kb_sync())
  65. logger.info("知识库定时同步已启动 (首次延迟 120s,间隔 3600s)")
  66. @app.on_event("shutdown")
  67. async def shutdown():
  68. from app.tools.java_client import JavaClient
  69. client = JavaClient()
  70. await client.close()