Skip to main content
Everything here works the same for every blob type. The typed modules are built on it.

Blobs

hub.blob(org, blob) sends one GET /blobs/{org}/{blob} and returns a Blob holding the record. From then on the blob is addressed by its canonical ids, so renaming the organization’s or the blob’s alias does not break a Blob you hold.
  • A missing blob raises PermissionDenied, not NotFound. The platform answers the same 403 for a blob that does not exist and for one your credential cannot see, so the two cannot be told apart.
  • The properties are a snapshot of the last read: id, alias, org_id, type, visibility, status, default_revision_id, and the whole record. blob.refresh() reads it again.
  • type is the blob’s type string, such as blobhub.model.onnx. See Blob Types.

Revisions

  • blob.revision(ref="default") reads one revision through Resolve Revision. ref is default or a revision id.
  • blob.revisions(page_size=50) yields every revision, newest first. It follows the listing’s cursor to the end and never stops early on a short page. See Pagination.
  • A Revision holds id, status, phase, comment, parent_id, updated_at and the whole record, and revision.refresh() reads it again.
A blob has one default revision and at most one draft. Writes go to the draft; a committed revision is read-only. The lifecycle is under Concepts → Revisions.

Creating and committing

blob.create_revision(comment, *, timeout=600.0) sends Create Revision, then polls until the new revision is ready. The draft starts with a copy of the default revision’s data and becomes the blob’s default.
  • The default revision must be committed first, or the call raises Conflict with error default_revision_not_committed. A blob with a draft as its default already has the one draft it may hold.
  • A blob at its revisions limit raises CommandError with error limit_exceeded.
revision.commit(comment=None, *, timeout=600.0) sends Commit Revision, then polls until the revision is ready in phase commit. A comment replaces the revision’s comment. A revision that is not a ready draft raises Conflict, with error revision_not_ready or revision_not_writable. Both calls wait. A revision that ends failed raises OperationFailed (revision_failed), and one still working when timeout runs out raises WaitTimeout, leaving the work running on the platform.

The data channel

Every blob type’s commands go through two routes on a revision. The SDK sends them for you:
The first argument is the command name, and every keyword becomes a field of the request body. A keyword set to None is left out, because the platform’s schemas refuse an explicit null. Nested values are sent as given. Each call returns the response’s JSON envelope as a dict; query_bytes also returns the binary payload. A committed revision answers a command with Conflict (revision_not_writable). The SDK never checks a phase or a status itself; the platform does, and its refusal arrives as an error. The commands each type accepts are in the Blob Types reference, such as the workflow type’s Create Session.

Typed modules

revision.typed() returns the typed module for the revision’s blob type, or the revision itself when the SDK has none: You can also construct a module directly, Onnx(revision). It raises TypeMismatch when the revision’s blob is of another type.

Operations

Some work finishes after the request that started it. The platform tracks it as an operation; today, that is the processing of an uploaded ONNX model.
status is in_progress, completed or failed. wait() returns once it is completed, raises OperationFailed when it is failed, and raises WaitTimeout when timeout runs out, leaving the operation running. An id that names no operation you can read raises PermissionDenied. Onnx.upload() starts and waits on one for you.

Raw requests

hub.request() sends any request relative to the API URL, with the same authentication, retries and error mapping as everything else, and returns the JSON envelope:
The first reads a revision’s readme through Resolve Metadata; the second lists an organization’s blobs through List Blobs. json= is sent exactly as given, and params= drops its None values. The path must be relative; an absolute URL raises ValueError. This is how you reach routes the SDK has no method for, such as creating a blob or minting an API key. hub.whoami() returns the calling user’s record from GET /users/me, or None for an anonymous client.

The client

A Client holds two HTTP connection pools, one for the API and one for presigned transfers. It is not thread-safe: use one per thread. Close it when you are done, or let a with block do it:

See also