Metadata-Version: 2.4
Name: apherisfold-cli
Version: 0.1.6
Summary: Prototype ApherisFold CLI for Hub-backed customer demos.
Author: Apheris
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jsonschema<5,>=4
Requires-Dist: rich<14,>=13
Requires-Dist: truststore<1,>=0.10
Requires-Dist: typer<1,>=0.12
Provides-Extra: dev
Requires-Dist: pytest<9,>=8; extra == "dev"
Requires-Dist: ruff<1,>=0.9; extra == "dev"
Dynamic: license-file

# ApherisFold CLI

This package contains the prototype customer-facing ApherisFold CLI for Hub
prediction, benchmark, and fine-tuning demos.

## Development

Use a project-local `venv`. Conda can coexist, but it should not be the primary
workflow for this CLI.

Bootstrap from the repository root:

```bash
task cli:bootstrap
```

That creates `cli/.venv`, installs the package in editable mode, and installs a
user-level shim at `~/.local/bin/apherisfold`.

### Running The CLI

The most reliable option, especially in mixed shell or Conda setups, is direct
binary invocation:

```bash
cd cli
./.venv/bin/apherisfold --help
```

If `~/.local/bin` is on `PATH`, `task cli:bootstrap` also enables:

```bash
apherisfold --help
```

Shell activation may work too, but it is optional and not the primary
recommendation.

## Usage

```bash
apherisfold --help
apherisfold login --profile apheris
apherisfold login --profile apheris-integ
apherisfold login --profile apheris-staging
apherisfold login --url https://hub.example.com
apherisfold login --url https://hub.example.com --callback-host localhost
apherisfold login status
apherisfold workflow list
apherisfold workflow list --status done --weight 3.0.0
apherisfold workflow list --workflow predict --tag smoke --id job_NUly
apherisfold workflow list --limit 50
apherisfold workflow list --limit -1
apherisfold --verbose=true workflow list
apherisfold workflow list --json
apherisfold workflow predict run --help
apherisfold workflow predict run --model openfold3 --weight 3.0.0 --output ./out --input ./request.json
apherisfold workflow predict run --model openfold3 --weight 3.0.0 --output ./out --input ./request.json --tag smoke --tag benchmark
apherisfold workflow predict run --model openfold3 --weight 3.0.0 --output ./out --input ./request.json --wait=true --result-view files
apherisfold workflow predict list
apherisfold workflow predict list --status done --tag smoke
apherisfold workflow predict list --limit 10
apherisfold workflow predict get --id job_NUlyMsnWq
apherisfold workflow benchmark run --model openfold3 --weight 3.0.0 --name "Baseline eval" --output ./out --input prediction_1.cif
apherisfold workflow benchmark run --model openfold3 --weight 3.0.0 --name "Baseline eval" --output ./out --input ./benchmark-inputs
apherisfold workflow benchmark list
apherisfold workflow benchmark list --status done --weight 3.0.0
apherisfold workflow benchmark get --id benchmark_abc123
apherisfold workflow fine-tune prepare --model openfold3 --weight 3.0.0 --name "Ligand tuning" --output ./out --training train_1.cif --training train_2.cif --validation validation.cif
apherisfold workflow fine-tune prepare --model openfold3 --weight 3.0.0 --name "Ligand tuning" --output ./out --training train.cif --validation validation.cif --hyper-params @fine-tune-params.json
apherisfold workflow fine-tune prepare --model openfold3 --weight 3.0.0 --name "Ligand tuning" --output ./out --training train.cif --validation validation.cif --batch-size 32 --learning-rate 0.0003 --maximum-training-time 86400
apherisfold workflow fine-tune run --id finetune_abc123
apherisfold workflow fine-tune list
apherisfold workflow fine-tune list --status running --name "FT Mock E2E"
apherisfold workflow fine-tune get --id finetune_abc123
apherisfold workflow fine-tune download-weight --id finetune_abc123 --step 16
apherisfold workflow fine-tune download-weight --id finetune_abc123 --step 16 --output ./weights/
apherisfold workflow fine-tune deploy-weight --id finetune_abc123 --step 16
apherisfold workflow fine-tune continue --id finetune_abc123 --duration 3600
apherisfold weights list
apherisfold weights list --model openfold3
apherisfold weights list --json
apherisfold --overwrite=true workflow predict run --model openfold3 --weight 3.0.0 --output ./out --input ./request.json
apherisfold --overwrite=true workflow predict download-result --id job_NUlyMsnWq --output ./job_NUlyMsnWq-results
apherisfold --overwrite=true workflow predict download-result --id job_NUlyMsnWq --output ./job_NUlyMsnWq-results --show
apherisfold --overwrite=true workflow benchmark download-result --id benchmark_abc123 --output ./benchmark_abc123-results
```

## Smoke Test Files

The repository includes ready-to-run examples under
[`cli/examples/smoke`](./examples/smoke):

- `request-minimal.json`: smallest useful protein-only request
- `request-protein-ligand.json`: protein + ligand request based on Hub/UI demo
- `request-multi-query.json`: two queries in one input file
- `protein_ligand.a3m`, `multimer_a.a3m`, `multimer_b.a3m`: sample repeatable assets
- `model-params.json`: fallback payload for `--model-params @...`
- `input.cif`: real ubiquitin ModelCIF matching `request-minimal.json`

Example commands:

```bash
cd cli

./.venv/bin/apherisfold workflow predict run \
  --model openfold3 \
  --output ./out-minimal \
  --weight 3.0.0 \
  --input ./examples/smoke/request-minimal.json

./.venv/bin/apherisfold workflow predict run \
  --model openfold3 \
  --output ./out-ligand \
  --weight 3.0.0 \
  --input ./examples/smoke/request-protein-ligand.json \
  --tag smoke \
  --tag ligand \
  --asset ./examples/smoke/protein_ligand.a3m \
  --diffusion-samples 5 \
  --seed 42

./.venv/bin/apherisfold workflow predict run \
  --model openfold3 \
  --output ./out-model-params \
  --weight 3.0.0 \
  --input ./examples/smoke/request-multi-query.json \
  --asset ./examples/smoke/multimer_a.a3m \
  --asset ./examples/smoke/multimer_b.a3m \
  --model-params @./examples/smoke/model-params.json

./.venv/bin/apherisfold workflow predict run \
  --model openfold3 \
  --output ./out-cif \
  --weight 3.0.0 \
  --input ./examples/smoke/input.cif
```

## Notes

- The current implementation is the `EN-5932` prototype milestone.
- `weights list` queries the Hub `GET /api/v1/models/installed` endpoint using
  the saved CLI login session.
- `workflow predict run` follows the same Hub submission path as the UI:
  it creates an input, uploads assets, and submits `POST /api/v1/requests`.
- Prediction and benchmark execution is centered on
  `workflow <workflow> run`. Fine-tuning uses `workflow fine-tune prepare`
  followed by `workflow fine-tune run --id <id>` so the uploaded dataset can be
  confirmed before training begins.
- `login` accepts either `--url` for an explicit Hub base URL or `--profile`
  for a built-in target. The current built-in profiles are `apheris`, which
  points at `https://try.fold.apheris.net` and uses runtime config from
  `https://try.fold.apheris.net/config.json`, `apheris-integ`, which points at
  `https://hub.integration.apheris.net` and uses runtime config from
  `https://hub.integration.apheris.net/config.json`, and `apheris-staging`,
  which points at `https://hub.staging.apheris.net` and uses runtime config
  from `https://hub.staging.apheris.net/config.json`.
- `login` uses a local PKCE callback at `http://127.0.0.1:8765/callback` by
  default. Use `--callback-host` when you need the same loopback flow on a
  different host name such as `localhost`.
- `weights list` exposes installed weights in a single `MODEL | MODEL VERSION |
  WEIGHT` table and also supports `--json` for machine-readable discovery.
- `--model-version` is optional when only one installed version is available
  for the chosen model. When `--model` is provided, the CLI accepts either the
  full `<model>:<version>` form or just the version suffix.
- The top-level command surface is `workflow`, `weights`, `login`, and
  `logout`.
- `workflow list` shows submitted Hub workflow runs across predict, benchmark,
  and fine-tune. It renders sectioned Rich tables for filters and runs.
- The default run table hides model and model version/build IDs. Use
  `--verbose=true workflow list` when you need the `MODEL` and `VERSION`
  columns.
- `workflow list` supports one filter per displayed column: `--id`,
  `--workflow`, `--model`, `--weight`, `--tag`, `--created-at`, and
  `--status`. Repeat filters to match multiple values.
- Run list filters are applied across the full returned run list before the
  row limit is applied. The default output shows the latest 30 matching rows.
  Use `--limit` to change the row count, and `--limit -1` to show all matching
  runs.
- `workflow predict list`, `workflow benchmark list`, and
  `workflow fine-tune list` filter the submitted run table to one workflow and
  accept the same model, weight, created-at, status, and id filters. Predict
  uses `--tag`; benchmark and fine-tune use `--name` (`--tag` remains accepted
  as a compatibility alias).
- `workflow predict get --id <job-id>`, `workflow benchmark get --id <id>`,
  and `workflow fine-tune get --id <id>` show stored Hub metadata for one run.
  Add `--json` to return the full Hub detail payload alongside the CLI summary.
- `workflow fine-tune prepare` creates the Hub fine-tune job, uploads repeated
  `--training` and `--validation` CIF/mmCIF files, writes `result.json`, and
  prints the `workflow fine-tune run --id <id>` command to run next.
- Fine-tune model settings are discovered from the wrapper schema used by the
  UI. Defaults are applied automatically, and schema properties are available
  as CLI flags by kebab-case name, for example `--batch-size 32`. Use
  `--hyper-params @fine-tune-params.json` for a raw Hub `hyperParams` object:

  ```json
  {
    "maximum_training_time": 86400,
    "batch_size": 32,
    "learning_rate": 0.0003,
    "warmup_steps": 50,
    "num_gradient_steps_per_epoch": 16,
    "training_seed": 42,
    "data_seed": 42,
    "precision": "bf16",
    "crop_size": 384,
    "ema_decay": 0.99,
    "metric_to_monitor": "lddt_inter_protein_ligand",
    "save_top_k": -1
  }
  ```
  
  Values from `--hyper-params` override schema defaults, and explicit flags
  such as `--batch-size 32` override the JSON file.
- `workflow fine-tune get --id <id>` renders the same three LDDT result groups
  as the UI: Protein-Ligand, Inter-Chain Protein, and Intra-Protein. Add
  `--json` for the machine-readable detail and result payload.
- `workflow fine-tune download-weight --id <id> --step <n>` resolves the
  persisted weight from the selected gradient step and downloads it locally.
  The default file name includes the fine-tune id and step, and `--output`
  accepts either a target file or a directory.
- `workflow fine-tune deploy-weight --id <id> --step <n>` resolves the same
  persisted weight and starts a deploy job. If `--description` is omitted, the
  CLI generates `<fine-tune name> step <n>`.
- `workflow fine-tune continue --id <id> --duration <seconds>` continues a
  completed run for additional training time.
- `workflow predict download-result --id <job-id> --output ./<job-id>-results`
  downloads predict outputs, extracts them locally, and writes a canonical
  `result.json` manifest for the downloaded files.
- `workflow benchmark download-result --id <id> --output ./<id>-results`
  exports the benchmark jobs table, including child job ids, statuses, metrics,
  and errors, to one benchmark-level `result.json` manifest.
- Add `--show` to `workflow predict download-result` when you want the
  downloaded payload printed directly in the terminal as well as written to
  disk.
- `workflow <workflow> run --help` shows available run flags, examples, and
  selector guidance for predict and benchmark. For fine-tuning, use
  `workflow fine-tune prepare --help`.
- Each workflow validates task-required options before execution and prints the
  available weight choices inline when `--weight` is missing or invalid.
- Every workflow help view includes example commands, and task metadata is
  expected to carry examples as part of the CLI contract.
- Reserved global flags such as `--config`, `--dry-run`, `--overwrite`, and
  `--resume` are shown in workflow help from the same metadata source.
- `--output`, `--model`, and `--weight` are explicit required workflow inputs.
  `--output` must
  point to an empty directory unless `--overwrite=true` is supplied.
- For `openfold predict`, `--input` is standardized as the primary input flag.
  The current prototype accepts file paths only and infers mode from the file
  extension: `.json` means Hub-style `requestParams`, `.cif` means CIF-start
  prediction setup.
- `workflow predict run` writes submission metadata to `result.json` and returns
  after the Hub request is created by default. With `--wait=true`, it polls the
  job, downloads the resulting files, and rewrites `result.json` as the
  canonical machine result containing both predicted structures and meta JSON.
- `--result-view full|files` controls whether downloaded predict outputs are
  embedded in `result.json` or represented by file paths only.
- Failed predict jobs now surface the request `state` field directly in
  `workflow predict get --id <job-id>`, with escaped wrapper JSON cleaned up
  for terminal readability when Hub persists that detail.
- MSA assets are optional in the CLI surface, matching Hub behavior when MSA
  server usage is enabled. Use `--asset file.a3m` only when you want to supply
  precomputed alignment files explicitly. The option is repeatable for multiple
  assets.
- `--tag` is repeatable for predict submissions. Query IDs from the input JSON
  are always appended to the submitted tags so CLI-created jobs match the UI
  tag behavior. When the input is a CIF, the default tag remains the file stem.
- For weights that support affinity, the CLI automatically runs affinity
  prediction. When a query has exactly one ligand chain it is selected
  automatically. Pass `--affinity-ligand <chain-id>` when a query contains
  multiple ligand chains to specify which one to use for affinity scoring.
  Queries without any ligand chain run as normal structure predictions.
- `--model-params` accepts raw Hub-style JSON, while flags like
  `--diffusion-samples` and `--seed` remain convenience overrides for common
  settings. `--use-msa` and `--use-template` are available as Protenix-specific
  convenience flags.
- There is no separate `module` abstraction in the prototype surface.
- Only workflow commands write artifacts; listing commands print directly to the
  terminal.
- Predict and benchmark execution happens via
  `apherisfold workflow <workflow> run`, with explicit `--model` and
  `--weight` parameters matching the current Hub weight picker UX. Fine-tune
  uses `prepare` and `run` because the Hub flow has a dataset upload phase
  before training starts.
- `workflow benchmark run` uses `--input`, mirroring predict. It accepts
  repeated CIF/mmCIF files or a directory containing CIF/mmCIF files and
  auto-detects matching `.a3m` files next to each structure.
- The current `.cif` input path is a mocked CIF-to-query conversion path so the
  prototype can exercise the intended CLI UX before real Hub integration lands.
- The CLI is intentionally minimal and customer-facing.
- Foundry RFCs are treated as an internal compatibility constraint, not as
  user-facing product vocabulary.
- Packaging is standard Python packaging: editable install for development,
  wheel/sdist for build artifacts, and `pipx` as the preferred future
  end-user install target.
