"""HF Spaces 单进程入口:后台线程起 FastAPI,前台起 Gradio(指回本机 API)。 Space 用 OpenAI 兼容后端(LLM_BACKEND=openai / EMBED_BACKEND=openai),端点与模型名经 Space secrets 注入:OPENAI_BASE_URL、OPENAI_API_KEY、MODEL_BASE、MODEL_FT (可选 OPENAI_EMBED_BASE_URL、FINSIGHT_EMBED_MODEL)。本地 `python app.py` 不设这些即走 Ollama。 """ import os import threading import time import requests import uvicorn API_PORT = int(os.getenv("API_PORT", "8000")) os.environ.setdefault("FINSIGHT_API", f"http://127.0.0.1:{API_PORT}") def _serve_api(): uvicorn.run("api.main:app", host="127.0.0.1", port=API_PORT, log_level="warning") def _wait_api(timeout: int = 30) -> bool: for _ in range(timeout * 2): try: requests.get(f"http://127.0.0.1:{API_PORT}/health", timeout=2) return True except Exception: time.sleep(0.5) return False def main(): # 知识库为空时用种子语料初始化(Space 首次启动 rag/.chroma 不在仓库里) try: from rag import KnowledgeBase, build_seed_kb if KnowledgeBase().count() == 0: build_seed_kb() print("seed KB built.") except Exception as e: print("seed KB init skipped:", e) threading.Thread(target=_serve_api, daemon=True).start() if not _wait_api(): print("⚠️ API 未就绪,前端仍会启动(各 Tab 会显示后端错误)。") from frontend.app import build build().launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860"))) if __name__ == "__main__": main()