Skip to main content

riffsdk

Python SDK for Riff. Provides sync and async clients for the Storage API, and lookups against an app's task board.

Installation

uv add riffsdk
# or
pip install riffsdk

Or install from a branch (for pre-release testing):

uv add git+https://github.com/databutton/riff-sdk-python.git@main
# or
pip install git+https://github.com/databutton/riff-sdk-python.git@main

Quick start

from riffsdk.storage import StorageClient

client = StorageClient()

# Upload (content type derived from the key: text/plain; charset=utf-8)
meta = client.put("hello.txt", "Hello, world!")
meta = client.put("notes.md", "# Title")      # -> text/markdown; charset=utf-8

# Download
data = client.get("hello.txt")

# List
for obj in client.list("hello"):
    print(f"{obj.key} ({obj.size} bytes)")

# Delete
client.delete("hello.txt")

client.close()

Async

from riffsdk.storage import AsyncStorageClient

async with AsyncStorageClient() as client:
    await client.put("key", b"data", content_type="application/octet-stream")
    data = await client.get("key")

Tasks

Look one task up on the app's task board, in whatever state it is in — completed ones included:

import riffsdk.tasks.v0 as tasks

task = tasks.get_task("TASK-42")   # display ID as it appears on the board, or the task's id

if task is None:
    ...                            # nothing on the board for this item
elif task["status"] == "completed":
    ...                            # already handled

This exists for trigger tools. A trigger is handed the tasks that still have work left on them and nothing about the ones already finished, so it cannot tell an item it has never seen from one whose task is done — and proposes the same finished work every time it fires. get_task closes that gap.

Import the version you are writing against, bound to a short name as above. A version does not change under you: when the API changes it appears as a new version, and the one you imported keeps behaving as it did. Importing riffsdk or riffsdk.tasks loads no version.

API

  • get_task(ref) -- returns a Task, or None if there is no such task. get_task_async is the async form.
  • Task is the task as JSON plus the version of that shape. Read fields by name (task["status"], task["metadata"], task.get("summary"), or task.data for the whole dict), so a task gaining a field needs no SDK release.
  • Raises TaskError if the lookup failed. A task that does not exist is not a failure; it comes back as None.
  • The board read is the app's own: a deployed app sees its production tasks, the same app in the workspace sees the workspace's. There is nothing to configure for that, and no way to read the other one.
  • Runs from an app's backend, where the environment it needs is already set.

Authentication

Set the RIFF_TOKEN environment variable. The SDK picks it up automatically.

API

Clients

  • StorageClient -- sync client
  • AsyncStorageClient -- async client

Both support: put, get, stat, exists, list, delete, close, and context manager usage.

Models

  • ObjectMeta -- metadata for a stored object (key, version, size, content_type, timestamps)
  • UploadResult, DownloadResult -- operation results
  • ListPage -- paginated listing
  • Scope -- access scope (use account_scope(), project_scope(), session_scope())

Uploads

  • ResumableUpload / AsyncResumableUpload -- multipart resumable uploads for large files
  • StorageReader / StorageWriter -- streaming read/write

Content types

content_type is optional on put, upload_file, upload_stream, begin_upload and create_write_stream. When omitted it is derived from the storage key's extension using a table bundled with the SDK, so the result does not depend on the host's /etc/mime.types or the Python version. Unknown extensions fall back to application/octet-stream.

  • upload_file prefers the key's extension and falls back to the local filename's -- so upload_file("docs/notes.md", "/tmp/tmpXY123") still stores text/markdown.
  • str payloads passed to put() are encoded as UTF-8, and get ; charset=utf-8 appended when the derived type is text/*.
  • An explicit content_type= is always used verbatim.

Exceptions

All exceptions inherit from StorageError:

  • AuthorisationError
  • ObjectNotFoundError
  • VersionConflictError
  • AlreadyExistsError
  • LeaseConflictError
  • UploadNotFoundError
  • QuotaExceededError
  • PartMismatchError
  • StorageTransportError

Examples

See the examples/ directory for complete working examples:

  • basic_crud.py -- put, get, list, delete
  • async_client.py -- async usage with asyncio
  • file_upload_download.py -- file uploads with progress
  • optimistic_concurrency.py -- version-based conflict handling
  • get_task.py -- reading the task board from a trigger tool

Development

Requires Python 3.11+ and uv.

uv sync --dev        # Install dependencies
mise run test        # Run tests
mise run lint        # Lint
mise run format      # Format code

See AGENTS.md for full development workflow details.

Metadata

Release files for riffsdk 0.18.0

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

Source distribution (sdist)

Source distribution for riffsdk 0.18.0
File Size Uploaded
riffsdk-0.18.0.tar.gz 121.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for riffsdk 0.18.0
File Interpreter ABI Platform
riffsdk-0.18.0-py3-none-any.whl Python 3 none any Details

Total release size: 164.9 kB

Release files / riffsdk-0.18.0.tar.gz

Download URL riffsdk-0.18.0.tar.gz
Size 121.4 kB
Tags Source
SHA-256 checksum
How to use checksums
3b617b40d023ffdcd4f5c7efee6bdd3b929d4970073e0114b68f17dc7ff33e04
BLAKE2b-256 checksum
How to use checksums
aad6a80946de558a0d311f0edde8739da62926812ed0ac91de7396d756cf8d34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release files / riffsdk-0.18.0-py3-none-any.whl

Download URL riffsdk-0.18.0-py3-none-any.whl
Size 43.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b6cab7d78971fd15c3df4d40a2036932da42ddf92da7edf345b42e70948cda10
BLAKE2b-256 checksum
How to use checksums
1b11457d68c9bc9151950a01882aec14eb43e994005a8a4459c90285479cfe4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.22.1

2 release files

0.22.0

2 release files

0.21.1

2 release files

0.21.0

2 release files

0.20.0

2 release files

This release

0.18.0 This release

2 release files

0.17.0

2 release files

0.16.1

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

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