hcc-meat-coder / app /cli.py
chraos's picture
Claude Opus 4.7 (1M context)
Initial scaffold: HCC-MEAT Coder v0.1.0
c6cfe5f
Raw History Blame Contribute Delete
2.88 kB
"""`hcc-meat` command-line interface.
hcc-meat code <note.txt> — run the pipeline on a single note, print JSON
hcc-meat gallery — dump the precomputed demo gallery
hcc-meat serve [--port 7860] — run the FastAPI backend with uvicorn
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
import typer
from rich.console import Console
from rich.table import Table
from app.pipeline import Pipeline
from app.pipeline.types import Note
app = typer.Typer(help=__doc__, no_args_is_help=True)
console = Console()
@app.command()
def code(
note_path: Path = typer.Argument(..., help="Path to a plain-text clinical note."),
json_out: bool = typer.Option(False, "--json", help="Emit full JSON."),
) -> None:
text = note_path.read_text()
result = Pipeline().run(Note(note_id=note_path.stem, text=text))
if json_out:
sys.stdout.write(result.model_dump_json(indent=2))
sys.stdout.write("\n")
return
table = Table(title=f"HCC suggestions for {note_path.name}")
table.add_column("HCC")
table.add_column("Label")
table.add_column("RAF")
table.add_column("Conf")
table.add_column("Trump", justify="center")
table.add_column("Risk")
table.add_column("MEAT (MEAT)")
for c in result.candidates:
cov = c.meat_coverage()
meat_str = "".join(
cat.value if cov[cat] else "·" for cat in list(cov.keys())
)
table.add_row(
c.hcc,
c.hcc_label,
f"{c.raf_weight:.3f}",
f"{c.confidence_calibrated:.2f}",
f"↓{c.hierarchy.trumped_by}" if c.hierarchy.trumped else "—",
c.risk.level.upper() if c.risk else "?",
meat_str,
)
console.print(table)
console.print(f"[dim]verifier drops: {result.verifier_drops} | latency: {result.latency_ms:.1f} ms[/dim]")
@app.command()
def gallery(
fixture: Path = typer.Option(
Path("tests/fixtures/regression_suite.json"),
help="Fixture file to run against.",
)
) -> None:
cases = json.loads(fixture.read_text())["cases"]
pipe = Pipeline()
out = []
for c in cases:
result = pipe.run(Note(note_id=c["case_id"], text=c["note_text"]))
out.append({
"case_id": c["case_id"],
"result": result.model_dump(),
})
sys.stdout.write(json.dumps(out, indent=2))
sys.stdout.write("\n")
@app.command()
def serve(
host: str = typer.Option("0.0.0.0", help="Bind host."),
port: int = typer.Option(7860, help="Bind port (7860 is HF Space default)."),
reload: bool = typer.Option(False, help="uvicorn --reload for dev."),
) -> None:
import uvicorn
uvicorn.run("app.api.server:app", host=host, port=port, reload=reload)
if __name__ == "__main__":
app()