#!/usr/bin/env python3 from __future__ import annotations import os import sys from pathlib import Path from fastapi import FastAPI PROJECT_ROOT = Path(os.environ.get("GENE_FAMILY_ROOT", "/data/gene-family-mas-v2")) GFANALYSIS_ROOT = Path(os.environ.get("GFANALYSIS_ROOT", "/data/wutx/00test/gfAnalysis")) for root in (PROJECT_ROOT, GFANALYSIS_ROOT): value = str(root) if value not in sys.path: sys.path.insert(0, value) from src.rag.qa_v1_1_73.api import router from src.rag.qa_v1_1_73.backend_guard import validate_backends from src.rag.qa_v1_1_73.soft_gate_policy import gate_policy app = FastAPI( title="Plant Biology QA V1.1.73", version="1.1.73", description=( "QA V1.1.73: graph-balanced top30 plus cascaded two-hop native Neo4j path chains. The top30 context keeps " "at least 15 graph-derived evidence items when available, and sends " "native graph chains as a separate output. Chat composes a validated final LLM answer; " "retrieval-only search returns evidence without an answer." ), ) app.include_router(router) @app.on_event("startup") def validate_production_backends() -> None: app.state.kb_backend_identity = validate_backends() @app.get("/health") def health(): return { "status": "ok", "service": "qa_v1_1_73", "version": "1.1.73-assertion-anchored", "gate_policy": gate_policy(), "backend": getattr(app.state, "kb_backend_identity", None), }