#!/usr/bin/env python3 """Bttoxin single-FNA pipeline CLI (pixi-based). This CLI uses pixi environments for execution: - digger environment: BtToxin_Digger with bioconda dependencies - pipeline environment: Python analysis with pandas/matplotlib/seaborn Example: python -m bttoxin.cli --fna tests/test_data/HAN055.fna --lang zh # With custom database python -m bttoxin.cli --fna tests/test_data/HAN055.fna --bttoxin_db_dir /path/to/bt_toxin """ from __future__ import annotations import argparse from pathlib import Path from .api import BtSingleFnaPipeline def main() -> int: ap = argparse.ArgumentParser(description="Bttoxin single-FNA pipeline (Digger → Shotter → Plot → Bundle)") ap.add_argument("--fna", type=Path, required=True, help="Path to a single .fna file") ap.add_argument("--toxicity_csv", type=Path, default=Path("Data/toxicity-data.csv")) ap.add_argument("--base_workdir", type=Path, default=None, help="Base working dir (default: runs/bttoxin under repo root)") ap.add_argument("--bttoxin_db_dir", type=Path, default=None, help="外部 bt_toxin 数据库目录路径(默认自动检测 external_dbs/bt_toxin)") ap.add_argument("--min_identity", type=float, default=0.0) ap.add_argument("--min_coverage", type=float, default=0.0) ap.add_argument("--disallow_unknown_families", action="store_true", default=False) ap.add_argument("--require_index_hit", action="store_true", default=False) ap.add_argument("--lang", type=str, choices=["zh", "en"], default="zh") ap.add_argument("--threads", type=int, default=4) args = ap.parse_args() pipe = BtSingleFnaPipeline(base_workdir=args.base_workdir) res = pipe.run( fna=args.fna, toxicity_csv=args.toxicity_csv, min_identity=args.min_identity, min_coverage=args.min_coverage, allow_unknown_families=not args.disallow_unknown_families, require_index_hit=args.require_index_hit, lang=args.lang, threads=args.threads, bttoxin_db_dir=args.bttoxin_db_dir, ) if not res.get("ok"): print(f"[bttoxin-run] FAILED at stage={res.get('stage')}") return 1 print("[bttoxin-run] ✓ Done") print(f" run_root: {res['run_root']}") print(f" digger: {res['digger_dir']}") print(f" shotter: {res['shotter_dir']}") print(f" bundle: {res['bundle']}") print(f" strain: {res.get('strain','')}") return 0 if __name__ == "__main__": raise SystemExit(main())