- 将手动触发爬取任务改为使用FastAPI后台任务执行 - 在职位处理逻辑中,将获取候选人列表改为线程池异步调用,避免阻塞事件循环 - 在候选人处理流程中,将获取简历详情改为线程池异步调用 - 在入库操作中使用线程池异步执行,提升处理性能 - 在Boss爬取任务中,将获取职位列表和获取候选人操作改为线程池异步调用 - 统一改造调用同步爬虫方法为异步线程池调用,提升整体异步性能和响应速度
126 lines
4.8 KiB
Python
126 lines
4.8 KiB
Python
"""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)
|