Quick Start
This guide walks through the shortest useful Python API lifecycle. You will create a repository, commit files, inspect history, read committed content, and materialize detached views for downstream tools.
The model in one minute
hubvault is not a mutable workspace. Keep three rules in mind:
writes are explicit commits
reads resolve a revision, usually
maindownload APIs return detached user views, not writable repository internals
That model is what makes the repository safe to move, archive, and reopen as a single directory.
Step 1: create a repository
Start from an empty directory:
from pathlib import Path
from hubvault import HubVaultApi
repo_dir = Path("demo-repo")
api = HubVaultApi(repo_dir)
info = api.create_repo()
print(info.default_branch)
# main
print(info.head is not None)
# True
create_repo() creates the repository layout and an empty Initial commit.
The repository starts with a valid history root, so normal history APIs work
immediately.
Step 2: add a single file
Use hubvault.api.HubVaultApi.upload_file() for the common one-file path:
weights_commit = api.upload_file(
path_or_fileobj=b"weights-v1",
path_in_repo="artifacts/model.safetensors",
commit_message="add model weights",
)
print(weights_commit.commit_message)
# add model weights
The method writes a real commit. It does not copy into a staging area and wait for a later action.
Step 3: make an explicit multi-operation commit
Use hubvault.api.HubVaultApi.create_commit() when you want a commit made
from explicit operations:
from hubvault import CommitOperationAdd
readme_commit = api.create_commit(
operations=[CommitOperationAdd("README.md", b"# Demo repo\n")],
commit_message="add readme",
)
print(len(readme_commit.oid))
# 40
Commit IDs are Git-compatible 40-hex identifiers. The public result is
hubvault.models.CommitInfo, aligned with commit-creation style APIs.
Step 4: inspect files and history
Now inspect the repository through read APIs:
print(api.list_repo_files())
# ['README.md', 'artifacts/model.safetensors']
commits = api.list_repo_commits(formatted=True)
print([item.title for item in commits])
# ['add readme', 'add model weights', 'Initial commit']
print(api.read_bytes("README.md").decode("utf-8").strip())
# # Demo repo
Use these APIs for day-to-day questions:
list_repo_files(): what exists at this revision?list_repo_commits(): what history produced this state?read_bytes(): what are the exact committed bytes for one file?
Step 5: inspect metadata for paths
Use get_paths_info() when you need public metadata rather than file bytes:
readme_info, model_info = api.get_paths_info(
["README.md", "artifacts/model.safetensors"]
)
print(readme_info.path)
# README.md
print(model_info.sha256 is not None)
# True
The public file model exposes user-facing oid / blob_id / sha256
values without requiring callers to understand the private storage layout.
Step 6: materialize detached views
Some tools need a real path. Use hf_hub_download() for one file:
download_path = api.hf_hub_download("artifacts/model.safetensors")
print(Path(download_path).as_posix().endswith("artifacts/model.safetensors"))
# True
Use snapshot_download() for a whole tree:
snapshot_dir = Path(api.snapshot_download())
files = sorted(
str(path.relative_to(snapshot_dir)).replace("\\\\", "/")
for path in snapshot_dir.rglob("*")
if path.is_file()
)
print(files)
# ['README.md', 'artifacts/model.safetensors']
These paths are detached views. Editing or deleting them does not corrupt committed repository data, and the views can be regenerated later.
Step 7: verify the repository
After meaningful writes, run the cheap integrity pass:
report = api.quick_verify()
print(report.ok)
# True
Use quick_verify() after normal operations. Use full_verify() for
maintenance windows, archival handoff, or suspicious repository states.
What this example demonstrates
The quick start covers the most important public guarantees:
repositories are usable immediately after creation
mutations happen only through explicit public write APIs
commit IDs are Git-compatible
read APIs resolve repository revisions
download and snapshot paths preserve repo-relative suffixes
detached views cannot mutate committed truth
Common mistakes
Avoid these assumptions:
editing a downloaded file changes the repository
there is a hidden mutable workspace
cache paths are permanent public storage
repository internals need to be edited manually
If you want a durable repository change, create a commit.
Complete example
from pathlib import Path
from hubvault import CommitOperationAdd, HubVaultApi
repo_dir = Path("demo-repo")
api = HubVaultApi(repo_dir)
info = api.create_repo()
print(info.default_branch) # main
print(info.head is not None) # True
weights_commit = api.upload_file(
path_or_fileobj=b"weights-v1",
path_in_repo="artifacts/model.safetensors",
commit_message="add model weights",
)
print(weights_commit.commit_message) # add model weights
readme_commit = api.create_commit(
operations=[CommitOperationAdd("README.md", b"# Demo repo\n")],
commit_message="add readme",
)
print(len(readme_commit.oid)) # 40
print(api.list_repo_files())
# ['README.md', 'artifacts/model.safetensors']
commits = api.list_repo_commits(formatted=True)
print([item.title for item in commits])
# ['add readme', 'add model weights', 'Initial commit']
print(api.read_bytes("README.md").decode("utf-8").strip())
# # Demo repo
readme_info, model_info = api.get_paths_info(
["README.md", "artifacts/model.safetensors"]
)
print(readme_info.path) # README.md
print(model_info.sha256 is not None) # True
download_path = api.hf_hub_download("artifacts/model.safetensors")
print(Path(download_path).as_posix().endswith("artifacts/model.safetensors"))
# True
snapshot_dir = Path(api.snapshot_download())
files = sorted(
str(path.relative_to(snapshot_dir)).replace("\\\\", "/")
for path in snapshot_dir.rglob("*")
if path.is_file()
)
print(files)
# ['README.md', 'artifacts/model.safetensors']
report = api.quick_verify()
print(report.ok) # True
Note
Commit IDs and cache paths vary between runs. The stable part is the public behavior: explicit commits, revision-based reads, and detached views.