Skip to content

feat(put): Hugging Face Hub storage backend ([71]) - #246

Merged
christophergeyer merged 1 commit into
rc/0.4.1from
cg/put-hf-backend
Jul 27, 2026
Merged

feat(put): Hugging Face Hub storage backend ([71])#246
christophergeyer merged 1 commit into
rc/0.4.1from
cg/put-hf-backend

Conversation

@christophergeyer

Copy link
Copy Markdown
Member

What

roar put hf://<owner>/<repo>[/path] (and hf://datasets/<owner>/<repo>) uploads artifacts to a HF repo and records the public resolve URL as the artifact's source_url/downloadLocation.

Why ([71], infra-spec §3)

The output-side of the lineage story — a reproduced model gets a canonical, stranger-fetchable home on HF (~14 TB free public), so the whole DAG is verifiable end to end (inputs from public sources, outputs pullable + hash-checkable). Closes "sourced-but-not-obtainable" for our own outputs. Sibling of [17] (roar get --cache).

How

  • storage/hf.py: HFBackendcreate_repo (idempotent) + upload_file via huggingface_hub, lazy-imported exactly like the GCS backend (only needed when you actually put hf://). Model repo by default; datasets//spaces/ prefixes supported; token from HF_TOKEN/~/.hf_token. URL convention matches the hf:// download side.
  • Wired hf into the put backend factory; recorded as a composite source_typedownloadLocation; added to put --help; huggingface_hub as a dev/optional dep.

Security note (campaign)

The deliberate publish uses a scoped, publish-time write token, distinct from the operator run's read-only token (risks C4/C5). Not an ambient credential.

Tests

9 unit tests (mocked HfApi) — parsing (model/dataset/space + subpaths), resolve URLs, upload args, exists-on-error. ruff + mypy + format clean.

Should ride the 0.4.1 release.

🤖 Generated with Claude Code

roar put hf://<owner>/<repo>[/path] (and hf://datasets/<owner>/<repo>) uploads
artifacts to a HF repo and records the public resolve URL as the artifact's
source_url/downloadLocation — the output-side of the lineage story: a reproduced
model gets a canonical, stranger-fetchable home, so the whole DAG is verifiable
end to end (infra-spec §3).

- storage/hf.py: HFBackend (create_repo idempotent + upload_file via huggingface_hub,
  lazy-imported like the gcs backend; model default, datasets/spaces prefixes;
  token from HF_TOKEN/~/.hf_token). Mirrors the hf:// download URL convention.
- publish.py: wire 'hf' into the put backend factory.
- put_preparation.py: record 'hf' as a composite source_type -> downloadLocation.
- put.py: hf:// destinations in --help.
- pyproject: huggingface_hub as a dev/optional dep (lazy at runtime, like boto3/gcs).
- tests: 9 unit tests (mocked HfApi) — model/dataset/space parsing, resolve URLs,
  upload args, exists. ruff + mypy clean.

Output-side sibling of [17] (roar get --cache). Should ride the 0.4.1 release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@christophergeyer
christophergeyer marked this pull request as ready for review July 27, 2026 16:07
@christophergeyer
christophergeyer merged commit f36edbd into rc/0.4.1 Jul 27, 2026
15 checks passed
@christophergeyer christophergeyer mentioned this pull request Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants