Skip to main content

hugging-bay

Promise: Find open model files with recorded SHA-256 and licence labels; verify downloaded bytes locally.
Install: python -m pip install hugging-bay
MCP config: {"mcpServers":{"hugging-bay":{"url":"https://huggingbay.xyz/api/mcp"}}} (Cursor; public reads need no account).
First call: Client().resolve("Qwen/Qwen3-0.6B")
Ask: Missing a model, file, tool or feature? Ask with request_feature (MCP) or POST https://huggingbay.xyz/api/v1/requests. No account. You get an id and can check its status. What shipped: https://huggingbay.xyz/changelog
Changelog · API docs
Keywords: gguf, local-llm, huggingface-alternative, mcp

Usage

from hugging_bay import Client

client = Client()  # defaults to https://huggingbay.xyz
# Optional auth: Client(token="sk-...") sends Authorization: Bearer <token>.
# The token is never printed in repr()/str() and never logged.

0. Get an API key (self-serve, optional)

Public discovery — search, resolve, download-plan, and hosted downloads — needs no token. You only authenticate for account workflows (saves, collections, watchlists). Minting a reader token is self-serve, with no signup and no prior auth:

from hugging_bay import Client

issued = Client().create_reader_token(display_name="my app", purpose="serving models")
token = issued["apiKey"]["token"]      # shown once — store it securely
client = Client(token=token)
print(client.me()["role"])             # validate the token

The full walkthrough (curl, JS/TS, MCP) is the one-screen quickstart at https://huggingbay.xyz/quickstart. A 401/403 from any authorized endpoint returns next.href = /quickstart#get-a-key, so there is no dead-end.

1. Find a commercial-safe model for a rig

from hugging_bay import Client

client = Client()
result = client.find_model(
    task="coding",
    gpu="rtx4090-24",
    ctx=8192,
    device_family="nvidia",
    commercial=True,
    limit=3,
)
best = result["bestPick"]
print(best["repo"], "-> safe-to-run:", best["safety"]["verdict"])

2. Verify a source URL

from hugging_bay import Client, HuggingBayError

client = Client()
try:
    resolved = client.resolve("Qwen/Qwen3-0.6B")
    print("resolved artifact:", resolved.get("artifactId") or resolved)
except HuggingBayError as err:
    print("could not resolve:", err.status, err.error)

3. Download a file and compare its SHA-256

from hugging_bay import Client

client = Client()
artifact_id = "hf-model-qwen-qwen2-5-0-5b-instruct-gguf"

# The hosted download plan includes per-file hashes and byte sizes.
plan = client.download_plan(artifact_id)

# Stream one hosted file, verify its exact plan hash, and record the completed
# pull. This stops the Hugging Bay redirect, follows the short-lived signed GCS
# URL without forwarding the API bearer, and only returns after attestation.
file = next(row for row in plan["files"] if row["path"].endswith(".gguf"))
# Case-only filename twins are refused by default. Opt in to suffix names
# allocated from the sorted full plan; generated suffixes skip every planned
# basename. The destination you pass supplies the selected file's base name,
# and existing unrelated names may advance its suffix. `pathMapping` reports
# the actual local path.
result = client.download_file(
    artifact_id,
    file["path"],
    "./models/" + artifact_id + "/" + file["path"],
    sha256=file["sha256"],
    size_bytes=file["sizeBytes"],
    on_case_collision="suffix",
)
print(result.get("pathMapping"))

Read-only against production (GET only, no token, no downloads):

from hugging_bay import Client

client = Client()  # https://huggingbay.xyz
page = client.search("embedding", limit=2, hosting="hosted")
pick = client.find_model("embeddings", hardware="8gb-laptop", limit=2)
resolved = client.resolve("Qwen/Qwen3-0.6B")
print(len(page["rows"]), pick.get("bestPick", {}).get("repo"), resolved.get("artifactId"))

Or run python examples/read_only.py (same host; optional HUGGING_BAY_ARTIFACT_ID).

4. Diagnose a failing run

from hugging_bay import Client

client = Client()
diagnosis = client.doctor(
    log_text="llama_model_load: error loading model: CUDA out of memory",
    runtime="llama.cpp",
)
if diagnosis["topFix"]:
    print("top fix:", diagnosis["topFix"])
for alt in diagnosis.get("smallerHostedAlternatives", []):
    print("smaller option:", alt)

Discovery → execution with Bay Run

BayRunClient runs the mirrored weights live on Bay Run (run.huggingbay.xyz, a separate origin). Take the next_call a catalog answer returns and run it — the client mints the anonymous $0 demo key for you and tolerates the edge's plain-text 429 "Rate exceeded.":

from hugging_bay import Client, BayRunClient

runnable = Client().find_runnable(task="embeddings", limit=1)
# hugging-bay.find-runnable.v1: the handoff lives at the top-level `next_call`
# (or under `recommendation.execution`); there is no `candidates` list.
next_call = runnable.get("next_call") or runnable["recommendation"]["execution"]

with BayRunClient() as run:            # mints a $0 demo key on first call
    out = run.run_next_call(next_call, input="text to embed")
    print(out)

# Or call the OpenAI-compatible surface directly:
with BayRunClient() as run:
    run.embeddings("BAAI/bge-small-en-v1.5", "hello world")
    run.rerank("BAAI/bge-reranker-base", query="q", documents=["a", "b"])
    run.run_pin("pin_abc123", input="...")

API surface

The new typed hosted methods require BayRunClient(enable_hosted_api=True). They are off by default. Existing execution methods keep their behavior. Use pins(), pin(id), mint_pin(request), instant_models(), instant_classify(request), instant_embed(request), instant_rerank(request), instant_chat(request), and coprocessor(request). auto_pins() and run_auto_pin(pin_id, request) call the preview CPU auto-pin routes. BayRunMcpClient maps MCP tool names list_auto_pins and run_auto_pin onto the same paths. Request and response types are in hugging_bay.bayrun_types.

provenance_keys() reads published Ed25519 keys. verify_receipt(receipt) checks a receipt locally with those keys. Unknown signers fail closed. Pin keys can differ from published provenance keys, so Pin verification may need an explicit trusted key document. Never use a receipt's embedded key as trust. The standalone hugging_bay.verify_receipt(receipt, keys) works offline. Verification authenticates signed claims. It does not prove model quality or the unsigned decision. For raw-result binding, set omit_raw_result=False when calling and pass result=... to verification.

With hosted methods enabled, the client retries 429 and 503 lane_cold once unless the server marks the error retriable: false. It accepts Retry-After seconds or HTTP dates and preserves the same body and idempotency key. A cold lane without a delay gets a one second retry. Delays above max_retry_after_seconds (default 120) raise BayRunError with the full .retry_after delay. Set honor_retry_after=False to let your application schedule retries. When the hosted flag is off, existing methods retain their 429/503 retry policy and 120 second cap.

See the hosted API guide and five examples.

Method Endpoint
create_reader_token(display_name, purpose) POST /api/account/reader-token (self-serve, no auth)
me() GET /api/me
find_model(task, gpu, ctx, device_family, commercial, limit, *, hardware, custom_memory_gb) GET /api/agents/find-model
artifact(id) GET /api/v1/artifacts/{id}
safety(id) GET /api/v1/artifacts/{id}/safety
bundle(id) GET /api/v1/artifacts/{id}/bundle
passport(id) GET /api/v1/artifacts/{id}/passport
resolve(repo_or_url) GET /api/v1/resolve?repo=
download_plan(id) GET /api/v1/artifacts/{id}/download-plan
download_file(id, path, destination, sha256, size_bytes, on_case_collision="error") GCS redirect + streamed SHA-256 verification + completion attestation; refuses case-folded path collisions by default, or returns deterministic .caseN destinations in pathMapping with on_case_collision="suffix"
doctor(log_text, runtime) POST /api/doctor
find_runnable(task, limit, commercial, **filters) GET /api/agents/find-runnable
recipes() / recipe(slug) GET /api/recipes[/{slug}]
verify_lock(lock_dict, root_dir) offline, stdlib only
BayRunClient.free_key() POST /v1/keys/free (Bay Run)
BayRunClient.models() GET /v1/models (Bay Run)
BayRunClient.run_pin(pin_id, ...) POST /v1/run/{pin_id} (Bay Run)
BayRunClient.embeddings / rerank / classify / chat(...) OpenAI-compatible (Bay Run)
BayRunClient.run_next_call(next_call, input) executes a catalog next_call

Errors

Every Hugging Bay error is the same typed envelope on every surface: {error, code, status, message, requestId, cause?, next}. Any response with status >= 400 raises HuggingBayError, which surfaces those fields directly — .error/.code (machine code), .message, .status, .request_id, .next (the {action, href} recovery step), .retry_after_seconds, and the raw .body. GET/HEAD reads retry 429 and 503 once using the largest valid Retry-After (seconds or HTTP-date) or JSON retry_after_s / retryAfterSeconds, plus positive jitter. Delays beyond 60 seconds surface as errors with the full delay; writes are single-shot. A successful X-HB-Backoff: v1 response with Retry-After paces the next read without replaying the success. See the backoff contract.

resolve() follows status-based error handling: a well-formed reference with no catalog match raises status 404; malformed/unsupported input raises 400 (invalid_query). Bay Run errors raise BayRunError, which is tolerant of the edge's non-JSON bodies and exposes .retry_after.

License

MIT

Public response note

Hugging Bay responses include a download note in note.summary. Current clients should read note, downloadable, and downloadStatus. Older clients that still need the previous response shape can opt in to it for one release; see the API reference.

Downloadable doesn't mean tested: this record says whether the exact file can be downloaded now, not that the model is complete or that it runs.

Release dependency

The request-and-status sentence above is approved copy held on the c29 AEO-72/AEO-73 deployment gate. Verify the deployed request_feature, get_request, and public changelog/status path before package publication or directory copy uses it.

Generated task client and resume

client.api exposes OpenAPI-generated task methods and typed dictionaries. client.search, client.artifact, client.find_runnable, client.deployment_plan and client.download_plan use these generated wire types. Deployment plans use GET /api/agents/deployment-plan?artifact=id; download plans keep their existing route.

Pass resume=True to client.download_file to retain interrupted bytes beside the destination. Retry the same call to continue. The SDK hashes the prefix again, validates the exact storage range, and checks the full SHA-256 before completion attestation and publication. A 200 response restarts the transfer. A crashed process can leave a lock; remove it only when no download is using it.

Run python examples/read_only.py for live GET-only reads. It never downloads model bytes or attests completion. See the SDK workflow for generation, drift checks and local packaging commands.

Parallel catalog swarms (opt in)

SwarmClient is an opt-in parallel catalog client: share one instance across threads, call pin() first, then use resolve_many, find_runnable_many and download_plans. It provides bounded concurrency, single-flight pinned-answer caching and shared Retry-After backoff. Server extensions remain disabled unless HUGGING_BAY_SWARM_FEATURES=1 is explicitly set. See [the swarm quickstart] (../../docs/swarm-quickstart.md) for limits, NDJSON, snapshot scope and a 50-worker example.

Metadata

Release files for hugging-bay 0.4.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hugging-bay 0.4.10
File Size Uploaded Provenance
hugging_bay-0.4.10.tar.gz 85.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for hugging-bay 0.4.10
File Interpreter ABI Platform
hugging_bay-0.4.10-py3-none-any.whl Python 3 none any Details

Total release size: 142.9 kB

Release files / hugging_bay-0.4.10.tar.gz

Download URL hugging_bay-0.4.10.tar.gz
Size 85.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c3791047920756d7cda12e1f8916b27e763d3c8d7c92c6b22daa9acb201a1a2c
BLAKE2b-256 checksum
How to use checksums
8703bcc4ecd9f3e180773d855ce5967640302ccd3c2986e35796b900ab93c886
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / hugging_bay-0.4.10-py3-none-any.whl

Download URL hugging_bay-0.4.10-py3-none-any.whl
Size 57.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ed85f9a6c3fd85ee82cd5a1f1bba608b104f80d7ba21b7d6636585ad14820936
BLAKE2b-256 checksum
How to use checksums
6a618fe2c8c19b2cd28f894a06bb4594a9aa1692f625b8bad6984f7e767661f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Security for hugging-bay 0.4.10

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page