from datetime import datetime, timedelta from typing import Optional from apscheduler.schedulers.asyncio import AsyncIOScheduler from fastapi import FastAPI from app.client.embedding_client_manager import EmbeddingClientManager, embedding_client from app.client.milvus_client_manager import milvus_client from app.client.mysql_client_manager import db_assistant_mysql_client_manager from app.repository.archive_messages_repository import ArchiveMessagesRepository from app.repository.milvus.summary_repository import SummaryRepository from app.summary.service import SummaryService from app.core.log import logger app = FastAPI(title="消息摘要服务", version="1.0") scheduler = AsyncIOScheduler(timezone='Asia/Shanghai') async def generate_daily_summary(date: Optional[str] = None): if not date: yesterday = datetime.now() - timedelta(days=1) date = yesterday.strftime("%Y-%-m-%-d") # 格式: 2026-6-15 logger.info(f"开始生成 {date} 的消息摘要...") try: db_assistant_mysql_client_manager.init() embedding_client.init() milvus_client.init() async with db_assistant_mysql_client_manager.session_factory() as db_assistant: archive_messages_repository = ArchiveMessagesRepository(db_assistant) summary_repository = SummaryRepository() service = SummaryService(archive_messages_repository, embedding_client, summary_repository) await service.get_message_summary(date) logger.info(f"{date} 消息摘要生成完成") except Exception as e: logger.error(f"生成摘要失败: {str(e)}", exc_info=True) raise finally: await embedding_client.close() @app.on_event("startup") async def startup_event(): scheduler.add_job( generate_daily_summary, trigger='cron', hour=2, minute=0, second=0, id='daily_summary', name='每日消息摘要任务', replace_existing=True ) scheduler.start() logger.info("定时任务调度器已启动,每天凌晨2:00自动执行消息摘要任务") @app.on_event("shutdown") async def shutdown_event(): scheduler.shutdown() logger.info("定时任务调度器已关闭") if __name__ == '__main__': import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)