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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hugging_bay-0.4.10.tar.gz | 85.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.