"""Server with API and Background Scheduler Usage: uv run python run_server.py uv run python run_server.py --host 0.0.0.0 --port 8000 uv run python run_server.py --no-scheduler # 只启动API,不启动定时任务 """ import argparse import sys import asyncio from pathlib import Path # 添加源码路径 src_path = Path(__file__).parent / "src" / "main" / "python" if str(src_path) not in sys.path: sys.path.insert(0, str(src_path)) import uvicorn from fastapi import FastAPI, BackgroundTasks from cn.yinlihupo.ylhp_hr_2_0.controller.api import create_app from cn.yinlihupo.ylhp_hr_2_0.service.scheduler import get_scheduler def create_combined_app(enable_scheduler: bool = True) -> FastAPI: """创建组合应用(API + 定时任务)""" app = create_app() if enable_scheduler: @app.on_event("startup") async def start_scheduler(): """应用启动时启动定时任务""" scheduler = get_scheduler() scheduler.start() @app.on_event("shutdown") async def stop_scheduler(): """应用关闭时停止定时任务""" scheduler = get_scheduler() scheduler.stop() # 添加调度器管理接口 @app.get("/api/scheduler/jobs") async def list_scheduler_jobs(): """获取定时任务列表""" scheduler = get_scheduler() return {"jobs": scheduler.get_jobs()} @app.post("/api/scheduler/jobs/{job_id}/pause") async def pause_scheduler_job(job_id: str): """暂停定时任务""" scheduler = get_scheduler() scheduler.pause_job(job_id) return {"success": True, "message": f"Job {job_id} paused"} @app.post("/api/scheduler/jobs/{job_id}/resume") async def resume_scheduler_job(job_id: str): """恢复定时任务""" scheduler = get_scheduler() scheduler.resume_job(job_id) return {"success": True, "message": f"Job {job_id} resumed"} @app.post("/api/scheduler/trigger/crawl") async def trigger_crawl(background_tasks: BackgroundTasks): """手动触发爬取任务""" scheduler = get_scheduler() background_tasks.add_task(scheduler._crawl_boss) return {"success": True, "message": "Crawl task triggered"} return app def main(): parser = argparse.ArgumentParser(description="简历智能体服务器 (API + 定时任务)") parser.add_argument("--host", default="0.0.0.0", help="绑定主机 (默认: 0.0.0.0)") parser.add_argument("--port", "-p", type=int, default=8000, help="绑定端口 (默认: 8000)") parser.add_argument("--reload", action="store_true", help="启用热重载 (开发模式)") parser.add_argument("--no-scheduler", action="store_true", help="不启动定时任务") args = parser.parse_args() enable_scheduler = not args.no_scheduler mode = "API + 定时任务" if enable_scheduler else "仅API" print(f""" ╔══════════════════════════════════════════════════════════════╗ ║ 简历智能体服务器 ║ ║ 模式: {mode:<20} ║ ╠══════════════════════════════════════════════════════════════╣ ║ 文档地址: http://{args.host}:{args.port}/docs ║ ║ API地址: http://{args.host}:{args.port}/api ║ ╚══════════════════════════════════════════════════════════════╝ """) # 创建组合应用 if args.reload: # 热重载模式需要使用导入字符串 import os os.environ["ENABLE_SCHEDULER"] = "true" if enable_scheduler else "false" uvicorn.run( "run_server:app", host=args.host, port=args.port, reload=True ) else: app = create_combined_app(enable_scheduler=enable_scheduler) uvicorn.run( app, host=args.host, port=args.port, reload=False ) # 全局应用实例(用于热重载模式) app = None if __name__ == "__main__": main() else: # 作为模块导入时(热重载模式) import os enable_scheduler = os.environ.get("ENABLE_SCHEDULER", "true") == "true" app = create_combined_app(enable_scheduler=enable_scheduler)