Files
PlantAI-rag-new/bioflow_service/app/config.py
T

134 lines
5.1 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.
"""config.py —— 生信服务(bioflow-service 8098)环境变量驱动配置(pydantic-settings)。
全部键可用环境变量覆盖(前缀 BIOFLOW_;LLM 沿用 docgen 的 DOCGEN_LLM_* 直连模式)。
零硬编码纪律:不出现任何写死宿主路径;仓库内相对路径按 __file__ 推导 repo 根。
"""
from __future__ import annotations
from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
_REPO_ROOT = Path(__file__).resolve().parent.parent.parent # bioflow_service/.. = 仓库根
def _resolve_root(v: str) -> str:
"""仓库内相对路径按 __file__ 推导 repo 根解析为绝对路径。"""
p = Path(v).expanduser()
if not p.is_absolute():
p = _REPO_ROOT / p
return str(p)
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
env_prefix="BIOFLOW_",
)
# ---- 应用 ----
app_name: str = "plantai-bioflow-service"
version: str = "0.1.0"
# ---- 阶段→镜像映射(A1 交付物,仓库内 bioflow_kernel/stage_image_map.json)----
image_map_path: str = "bioflow_kernel/stage_image_map.json"
# ---- 数据与任务目录 ----
data_root: str = "bioflow_data" # 生信数据根(hmm/rag_db 等,只读挂载进容器)
jobs_dir: str = "bioflow_data/jobs" # 任务目录根(input/workspace/events)
db_path: str = "bioflow_data/bioflow.db" # 独立 SQLite(与 BFF 完全隔离,FR-BIO-028)
archives_dir: str = "bioflow_data/archives"
# ---- 执行 ----
concurrency: int = 3 # 全局并发信号量上限(FR-BIO-031,可配)
stage_timeout_sec: float = 36000.0 # 单阶段 docker 硬超时(秒,10h)
docker_image_tag_suffix: str = "dev" # 镜像 tag 后缀(P0 交付物为 :dev)
host_uid_env: str = "BIOFLOW_HOST_UID" # 宿主机 uid 环境变量名;未设置时回退服务进程 uid
container_data_dir: str = "/bioflow-data"
container_input_dir: str = "/job/input"
container_workspace_dir: str = "/job/workspace"
default_cpus: str = "4"
default_memory: str = "32g"
log_tail_lines: int = 80 # manifest 接口日志尾行数(≤80)
max_upload_gb: float = 100.0 # 上传大小上限(GB;超限 413)
upload_ext_allow: str = ".fasta,.fa,.faa,.fna,.pep,.cds,.gz,.gff,.gff3,.gtf,.txt,.tsv,.csv,.xlsx,.xls,.bed,.vcf,.vcf.gz,.bam,.cram,.sam,.hmm,.nwk,.newick,.treefile,.json,.yaml,.yml,.pdf"
# ---- 规划(planner)----
llm_plan_timeout: float = 60.0 # 规划 LLM 单次调用超时(秒)
plan_candidates: int = 3 # 候选路径条数(2~3,FR-BIO-002)
plan_max_rounds: int = 2 # LLM 输出硬校验失败的最多重试轮数
# ---- 知识库(vstore/flow.py 本地实例;无 vstore 时自动降级 llm_only)----
flow_docs_dir: str = "vstore/data/flow_docs"
# ---- LLM(沿用 docgen deepseek 直连模式,DOCGEN_LLM_* 键)----
docgen_llm_base_url: str = "https://api.deepseek.com/v1"
docgen_llm_api_key: str = ""
docgen_llm_model: str = "deepseek-chat"
docgen_llm_timeout: float = 300.0
# ---- 报告登记(BFF 反代端点;空=未配置,登记降级为仅落表)----
service_url: str = "http://127.0.0.1:8098"
# ---- 容器环境变量(BBA_*;零硬编码:路径全部从本配置推导)----
@property
def bba_env(self) -> dict[str, str]:
"""docker run 注入的 BBA_* 环境(值全部来自配置推导,无写死宿主路径)。"""
return {
"BBA_PFAM_DIR": f"{self.container_data_dir}/hmm",
"BBA_RAG_MAPPING_FILE": f"{self.container_data_dir}/rag_db/pfam_mapping.json",
"BBA_DISABLE_RAG_PFAM_LOOKUP": "0",
}
@property
def host_uid(self) -> int:
"""--user 注入 uid:BIOFLOW_HOST_UID 环境变量优先,否则服务进程 uid。"""
import os
raw = os.environ.get(self.host_uid_env, "").strip()
if raw:
try:
return int(raw)
except ValueError:
pass
return os.getuid()
@property
def image_map_abs(self) -> str:
return _resolve_root(self.image_map_path)
@property
def data_root_abs(self) -> str:
return _resolve_root(self.data_root)
@property
def jobs_dir_abs(self) -> str:
return _resolve_root(self.jobs_dir)
@property
def db_path_abs(self) -> str:
return _resolve_root(self.db_path)
@property
def archives_dir_abs(self) -> str:
return _resolve_root(self.archives_dir)
@property
def flow_docs_dir_abs(self) -> str:
return _resolve_root(self.flow_docs_dir)
@property
def upload_ext_set(self) -> set[str]:
return {ext.strip().lower() for ext in self.upload_ext_allow.split(",") if ext.strip()}
@lru_cache(maxsize=1)
def get_settings() -> Settings:
return Settings()
settings = get_settings()