This repository has been archived on 2026-03-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
YLHP_HR_2.0/run_server.py
JiaoTianBo 3c29ca04eb feat(api): 使用FastAPI重构招聘者账号管理与启动服务器
- 移除旧的命令行工具add_recruiter.py和main.py,统一改用API方式管理招聘者账号
- 新增FastAPI应用,提供招聘者账号的CRUD接口及激活/停用功能
- 添加CORS中间件,支持跨域请求
- 支持通过API接口创建、查询、更新、删除招聘者账号,并返回标准化响应
- 集成异步后台定时任务调度器,定时爬取Boss直聘简历和分析报告
- 新增run_server.py启动脚本,支持启动FastAPI服务器和定时任务调度器的组合应用
- 定时任务支持任务列表查询、暂停、恢复及手动触发爬取任务的API
- 更新pyproject.toml依赖,新增fastapi、uvicorn和apscheduler等库
- 优化系统架构,实现Web API和后台调度功能解耦与整合,提高系统扩展性及易用性
2026-03-24 14:50:50 +08:00

126 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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
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():
"""手动触发爬取任务"""
scheduler = get_scheduler()
asyncio.create_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)