| """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(): |
| |
| 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() |
|
|