blobhub.connect() needs two things: an API key, or none for anonymous reading, and the URL of the API. It resolves
each one on its own, from the first source that has it. It reads the profiles that
blobhub login stores and never writes them.
The order
hub.identity.source names the rung the key came from: argument, env, profile:<name> or anonymous.
hub.identity.api_url is the URL in use, with any trailing / removed.
- An empty value counts as unset.
BLOBHUB_API_KEY=""falls through to the next rung. - There is no default organization. blobhub-cli’s
BLOBHUB_ORGmeans nothing here: every SDK call names its blob in full, as an organization and a blob.
The profile file
Profiles live in~/.blobhub/credentials.yaml, the file blobhub-cli and blobhub-worker share. Its shape is
described under CLI configuration:
- The SDK only reads it. It never creates the file, writes it, or changes its mode. Store a profile with
blobhub login, from blobhub-cli, orblobhub-worker login. - It reads
default, and each profile’skeyandurl. It ignoresrealtime_urland anything else. - Its place is fixed. It is always
.blobhub/credentials.yamlin your home directory; no environment variable moves it. - It is read on every
connect()exceptconnect(anonymous=True), even when you passapi_key=. A file the SDK refuses failsconnect(api_key=…)too, so fix the file rather than working around it. - A missing file is not an error. It contributes no profiles and no default.
connect() raises blobhub.ConfigError:
invalid_credentials_file covers a file that is not UTF-8 text, is not valid YAML, has no profiles map, holds a
profile without a non-empty key and url, or has a default that is not a string.
A named profile must exist even when a key is set. A profile is named by profile=, BLOBHUB_PROFILE or the
file’s default:, and BLOBHUB_PROFILE=ci with BLOBHUB_API_KEY exported still raises profile_not_found if the
file has no ci profile. The SDK refuses a loose file mode instead of repairing it, as blobhub-cli and
blobhub-worker do.
Anonymous reading
With no key from any rung, the SDK reads as an anonymous visitor. It fetches a token fromGET /auth/core/anonymous on the first request, keeps it in memory only, and
renews it through Refresh Token when it is about to expire or is refused.
connect(anonymous=True) asks for that on purpose:
- It reads neither the profile file nor
BLOBHUB_API_KEYnorBLOBHUB_PROFILE, so a stale, loose or foreign profile cannot break it. This is what the public notebooks use. - It still honours
api_url=andBLOBHUB_API_URL. - Combined with
api_key=orprofile=, it raisesValueError.
AuthError or PermissionDenied; the SDK
never retries the request anonymously. The fallback runs only when no key resolved at all, and because that is
silent, an AuthError or PermissionDenied raised for an anonymous request says in its message that the client
is anonymous and where a key would come from.
Which credential reads what
An API key reaches what it was minted for (see API Key Authentication):- A user-scoped key acts as its user, capped at the key’s role: it reaches what the user reaches through ownership and membership, and reads public blobs in public organizations, as a signed-in user does.
- An org-scoped key reaches blobs in its own organization.
- A blob-scoped key reaches its own blob.
PermissionDenied. To read
public content elsewhere with one, such as the models in onnx-vision-models, connect a second client with
connect(anonymous=True). One process can hold both clients.
In CI and containers
Export the key, and the URL if you are not using the default. No file is needed:hub.identity, not in a repr, not in an error message or a log line.
See also
blobhub login— stores a profile.- CLI configuration — the credentials file and how blobhub-cli resolves a credential.
- Service accounts — a key that is an account of its own, for automation.
- Errors and retries —
AuthError,PermissionDeniedandConfigErroramong the rest.

