- 全链路:多源JD接入/清洗交叉验证/结构化抽取(星火+离线双通道)/时序知识图谱/新岗位发现/演化分析/人岗匹配/学习路径 - WebUI 五视图:驾驶舱/图谱工作台/岗位演化/匹配(单人+批量)/学习路径 - 设置中心(config.json)/Token鉴权/SQLite状态库/语义向量通道(BGE-M3本地或联网API) - 71 个 pytest 用例;数据目录仅保留结构(.gitkeep),数据由 scripts/generate_dataset.py 复现
63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
"""应用装配层:日志、图谱初始化、服务启动。
|
||
|
||
main.py 只做一件事——调用本模块的 run()。分层关系:
|
||
|
||
main.py 唯一入口(装配)
|
||
└─ app.bootstrap 启动流程(本模块)
|
||
├─ app.config 配置加载(config.yaml + config.json)
|
||
├─ app.services 端到端 pipeline 编排
|
||
└─ app.api.routes FastAPI 接口层(uvicorn 托管)
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
import threading
|
||
import time
|
||
import webbrowser
|
||
|
||
import uvicorn
|
||
|
||
from app.config import load_config, resolve
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def setup_logging() -> None:
|
||
"""全局日志:时间 | 级别 | 模块 | 消息。"""
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
|
||
)
|
||
|
||
|
||
def ensure_graph(cfg: dict) -> None:
|
||
"""图谱不存在时先跑一遍端到端 pipeline 构建。"""
|
||
graph_path = resolve(cfg, "graph_path")
|
||
if graph_path.exists():
|
||
logger.info("检测到已有图谱 %s,直接加载", graph_path)
|
||
return
|
||
logger.info("图谱不存在,先执行端到端 pipeline 构建……")
|
||
from app.services.pipeline import run_pipeline
|
||
stats = run_pipeline(cfg)
|
||
logger.info("图谱构建完成:%s", stats["stages"].get("graph"))
|
||
|
||
|
||
def _open_browser_later(url: str, delay: float = 1.5) -> None:
|
||
time.sleep(delay)
|
||
try:
|
||
webbrowser.open(url)
|
||
except Exception as exc: # 浏览器打不开不影响服务
|
||
logger.warning("自动打开浏览器失败:%s,请手动访问 %s", exc, url)
|
||
|
||
|
||
def run() -> None:
|
||
"""启动流程:日志 → 配置 → 图谱 → 服务 → 自动开浏览器。"""
|
||
setup_logging()
|
||
cfg = load_config()
|
||
ensure_graph(cfg)
|
||
host, port = str(cfg["host"]), int(cfg["port"])
|
||
url = f"http://{host}:{port}"
|
||
logger.info("CareerNexus 职联启动中:%s", url)
|
||
threading.Thread(target=_open_browser_later, args=(url,), daemon=True).start()
|
||
uvicorn.run("app.api.routes:app", host=host, port=port, log_level="info")
|