upstash-blob is the Python SDK. It has a sync Bucket and an async AsyncBucket, and an upload handler for each that serves the browser client, so a React app can upload straight to storage through a Python backend.
This section is the Python reference: names, types, and framework wiring. What each call does, its defaults and its limits are on the concept pages it links to.
Install#
It needs Python 3.10 or later, and its one dependency is httpx. FastAPI, Django, Flask, pydantic and boto3 are not pulled in; the modules that use them import them only when you do.
Modules#
| Import | Exports |
|---|---|
upstash_blob | Bucket, AsyncBucket, UploadHandler, AsyncUploadHandler, UploadRoute, BeforeUploadResult, unique_path, BlobError, format_bytes, and the types |
upstash_blob.fastapi | upload_view, for an AsyncUploadHandler on FastAPI or Starlette |
upstash_blob.django | upload_view, for either handler |
upstash_blob.flask | upload_view, for an UploadHandler |
There is no Python browser client. The browser runs @upstash/blob/react or @upstash/blob/browser, which speak the same protocol to a Python handler as to a TypeScript one; see With a server in another language.
Bucket and AsyncBucket#
The two have the same methods, options and records. Every AsyncBucket method is awaited, including public_url() and s3(), except stream(), which is async with and yields an AsyncBlobStream. Its put also takes async iterables as a body. Use AsyncBucket under FastAPI, Starlette or any other asyncio code, and Bucket everywhere else.
Each bucket holds an httpx client with its own connection pool. A bucket built once at import lives as long as the process and needs no closing. One you build for a single job closes with a context manager:
close() and await aclose() do the same by hand.
The Bucket client#
Bucket.from_env() is the same constructor with the token read from UPSTASH_BLOB_TOKEN. It takes the same keyword options, and a variable name when the token lives somewhere else:
An unset or empty variable raises a TypeError when the bucket is built, not on the first request.
| Option | Type | Description |
|---|---|---|
token | str | Required, and the only positional argument. See Connecting. |
cache | CacheOption | The default Cache-Control for every object this client stores. A per-call cache overrides it. See Caching. |
enable_telemetry | bool | False turns telemetry off for this client. See Telemetry. |
retry | RetryConfig | Literal[False] | False, or {"retries": ..., "backoff": ...}. See Retries. |
http_client | httpx.Client / httpx.AsyncClient | Sends every request, for a proxy or custom timeouts. A client you pass is never closed by the bucket. |
AsyncBucket takes an httpx.AsyncClient; Bucket takes an httpx.Client.
There is no visibility option. Whether the bucket is public or private is a console setting; see Connecting.
Retries#
| Field | Type | Description |
|---|---|---|
retries | int | Retries after the first attempt, for every request this client makes. |
backoff | Callable[[int], float] | Milliseconds before retry n, counted from 0. A Retry-After from the service wins over it. |
RetryConfig is the TypedDict for this shape. An unknown key, a negative count or a backoff that is not callable raises a TypeError when the bucket is built. Which requests are retried, and the default budget and backoff, are on Retries.
Using an S3 client#
bucket.s3() returns an S3Config with the endpoint, region, bucket name and a short-lived credential. client_kwargs() is what boto3.client("s3", ...) takes. On AsyncBucket, s3() is awaited.
Unlike the TypeScript config, the credential is a fixed value, not a provider: boto3 cannot refresh it. It stops working at cfg.expires_at, so build a new client from a fresh bucket.s3() before then.
What an S3 client is for, and why it must not presign, is on Using an S3 client.
Option types#
| Type | Python | Grammar |
|---|---|---|
Size | int | str | Size |
Duration | int | float | str | timedelta | Duration. A timedelta counts as its total seconds. |
CacheOption | Duration | Literal["immutable", "revalidate", "no-store"] | CacheOption. A raw header is a str. |
MultipartOption | bool | Size | Changing the threshold |
All four are exported from upstash_blob.
A value of the wrong type, such as a bool size, raises a TypeError. A string that does not parse, such as "5mbit", raises a ValueError naming the option. Both are raised by the call that takes the option, except a cache on the client, which is checked on each call that stores an object. See Bad options.
Every size the SDK returns is an int of bytes. format_bytes(2_400_000) is '2.4 MB', the same text the browser client shows.