Skip to main content

UmaDB Python Client

The Python package umadb provides a synchronous client for reading and appending events to UmaDB over its gPRC API using Rust-powered bindings via PyO3.

It is adapted into the Python eventsourcing library via the eventsourcing-umadb package.

Installation

From PyPI

To install with pip, create and activate a virtual environment, then:

pip install umadb

Running the UmaDB Server from Python Package

The package installs a server script named umadb.

umadb --help

This script starts the UmaDB server in-process via the Rust/PyO3 bindings (it does not require an additional external umadb binary).

Script options

The script supports the same key startup options as the Rust CLI:

  • --listen
  • --db-path
  • --tls-cert
  • --tls-key
  • --api-key
  • --read-method
  • --page-cache-max-pages
  • --page-cache-max-mb
  • --zero-fill-pages / --no-zero-fill-pages

Environment variables

If command-line options are not provided, the script reads these environment variables:

  • UMADB_LISTEN
  • UMADB_DB_PATH
  • UMADB_TLS_CERT
  • UMADB_TLS_KEY
  • UMADB_API_KEY
  • UMADB_READ_METHOD
  • UMADB_PAGE_CACHE_MAX_PAGES
  • UMADB_PAGE_CACHE_MAX_MB
  • UMADB_ZERO_FILL_PAGES

Boolean environment variable values accepted for UMADB_ZERO_FILL_PAGES are: 1/0, true/false, yes/no, and on/off (case-insensitive).

Option precedence is:

  1. Explicit command-line argument
  2. Environment variable
  3. Built-in default

Example

UMADB_LISTEN=0.0.0.0:50051 UMADB_DB_PATH=./uma.db umadb

Connecting to UmaDB

Use the Client class as the main entry point for connecting to an UmaDB server.

class Client(
    url: str,
    ca_path: str | None = None,
    api_key: str | None = None,
    batch_size: int | None = None,
):
    ...

Parameters

Name Type Description
url str Required connection string. If the argument starts with https or grpcs, a secure TLS channel is created; otherwise an insecure channel is used.
ca_path str|None Optional path to a PEM-encoded root/CA certificate for TLS connections (useful for self-signed servers).
api_key str|None Optional API key used for authenticating with the server.
batch_size int|None Optional hint for how many events to buffer per batch when reading. The server may cap this; a sensible default is used if unset..

Connection Examples

from umadb import Client

# Insecure (no TLS)
client = Client("http://localhost:50051")

# Secure with TLS (system CAs)
client = Client("https://example.com:50051")

# Secure with TLS using self-signed CA
client = Client(
    url="https://localhost:50051",
    ca_path="server.pem",
)

# TLS + API key
client = Client(
    url="https://example.com:50051",
    ca_path="server.pem",
    api_key="umadb:example-api-key-4f7c2b1d9e5f4a038c1a",
)

# TLS + API key + batch size hint
client = Client(
    url="https://example.com:50051",
    ca_path="server.pem",
    api_key="umadb:example-api-key-4f7c2b1d9e5f4a038c1a",
    batch_size=1000,
)

Appending Events

The Client.append() method writes new events to an UmaDB server.

def append(
    events: list[Event],
    condition: AppendCondition | None = None,
    tracking_info: TrackingInfo | None = None,
) -> int:
    ...

The Client.append() method can be used to append new Event instances to UmaDB atomically, with an optional append condition, and optional tracking information. Events are written in order.

Conditional appends with event UUIDs are idempotent. The server does not enforce uniqueness of events IDs.

Parameters

Name Type Description
events list[Event] The list of events to append. Each includes an event type, tags, and data payload.
condition AppendCondition|None Optional append condition to ensure no conflicting writes occur.
tracking_info TrackingInfo|None Optional tracking information – for event-processing components only.

Return Value

Returns the sequence number (int) of the last successfully appended event from this operation. This value can be used to wait for downstream event-processing components in a CQRS system to become up-to-date.

Example

import uuid

from umadb import AppendCondition, Client, Event, IntegrityError, Query, QueryItem

client = Client("http://localhost:50051")

# Define a consistency boundary (same query you use while reading)
cb = Query(items=[QueryItem(types=["example"], tags=["tag1", "tag2"])])

# Read to build decision model
read_resp = client.read(query=cb)
for r in read_resp:
    print(f"Existing event at {r.position}: {r.event}")

last_known = read_resp.head()
print("Last known position:", last_known)

# Produce a new event with a UUID (for idempotent retries) and some metadata
ev = Event(
    event_type="example",
    tags=["tag1", "tag2"],
    data=b"Hello, world!",
    uuid=uuid.uuid4(),
    metadata={"source": "readme", "correlation_id": str(uuid.uuid4())},
)

# Append with an optimistic condition: fail if conflicting events exist after last_known
cond = AppendCondition(fail_if_events_match=cb, after=last_known)
position1 = client.append([ev], condition=cond)
print("Appended at:", position1)

# Conflicting append should raise an error (e.g. ValueError)
try:
    client.append(
        [
            Event(
                event_type="example",
                tags=["tag1", "tag2"],
                data=b"Hello, world!",
                uuid=uuid.uuid4(),
            )
        ],
        condition=cond,
    )
except IntegrityError as e:
    print("Conflicting event was rejected:", e)

# Idempotent retry with same event UUID and condition should return same commit position
position2 = client.append([ev], condition=cond)
assert position1 == position2
print("Idempotent retry returned position:", position2)

Reading Events

The Client.read() method returns recorded events from an UmaDB server.

def read(
    query: Query | None = None,
    start: int | None = None,
    backwards: bool = False,
    limit: int | None = None,
) -> ReadResponse:
    ...

The Client.read() method can be used both for constructing decision models in a domain layer, and for projecting events into materialized views in CQRS. An optional Query can be provided to select by tags and types.

Parameters

Name Type Description
query Query|None Optional structured query to filter events (by tags, event types, etc).
start int|None Read events from this sequence number. Only events with positions greater than or equal will be returned (or less than or equal if backwards is True.
backwards bool If True events will be read backwards, either from the given position or from the last recorded event.
limit int|None Optional cap on the number of events to retrieve.

Return Value

Returns an iterable "read response" instance from which SequencedEvent instances, and the most relevant "last known" sequence number, can be obtained.

Example

from umadb import Client, Query, QueryItem

client = Client("http://localhost:50051")

# Filter by type(s) and tag(s)
q = Query(items=[QueryItem(types=["example"], tags=["tag1", "tag2"])])

resp = client.read(query=q, start=None, backwards=False, limit=None)
for item in resp:
    print(f"Got event at position {item.position}: {item.event}")

last_known = resp.head()
print("Last known position:", last_known)

Subscriptions

The Client.subscribe() method returns recorded events from an UmaDB server, keeping the stream open to deliver future events as they arrive.

def subscribe(
    query: Query | None = None,
    after: int | None = None,
) -> Subscription:
    ...

The Client.subscribe() method can be used for projecting events into materialized views in CQRS. An optional query can be provided to select by tags and types.

Parameters

Name Type Description
query Query|None Optional structured query to filter events (by tags, event types, etc).
after int|None Read events after this sequence number. Only events with a larger sequence number will be returned.

Return Value

Returns an iterable "subscription" instance from which SequencedEvent instances can be obtained.

Example

from umadb import Client, Query, QueryItem

client = Client("http://localhost:50051")

# Filter by type(s) and tag(s)
q = Query(items=[QueryItem(types=["example"], tags=["tag1", "tag2"])])

# Subscribe to all events
for se in client.subscribe():
    print("New event:", se.position, se.event)
    # Break for demo purposes
    break

Getting Head Position

The Client.head() method returns the position of the last event recorded in an UmaDB server.

def head(self) -> int | None: ...

The Client.head() method can be used for counting the number of recorded events in the database, or for determining the position of the last recorded event when subscribing only to new events.

Return Value

Returns the position (u64) of the last recorded event in the event store, or None if no events have been recorded yet.

Getting Tracking Info

The Client.get_tracking_info() method returns the last recorded position in an upstream sequence of events.

def get_tracking_info(self, source: str) -> int | None: ...

The Client.get_tracking_info() method can be used when starting or resuming an event-processing component. The event-processing component will start by requesting new events from the upstream sequence after this position. The position of an upstream event that has been processed successfully can be recorded atomically when appending new events generated by processing that event.

Parameters

Name Type Description
source str Upstream source name.

Returns the last recorded upstream position (int), or None if the sequence name is not found.

Event

An Event represents a single event either to be appended or already stored in the event log.

Field Type Description
event_type str The event’s logical type (e.g. "UserRegistered").
tags list<str> Tags assigned to the event (used for filtering and indexing).
data bytes Binary payload associated with the event.
uuid str|None Unique event ID.
metadata dict[str, str] Optional string key/value pairs stored alongside the event.

Idempotent support for append operations is activated by setting a UUID on appended events.

event_type and each tag in tags may be up to 65535 bytes long. Appending an event with a longer type or tag fails with a validation error (ValueError).

metadata is for information about the event (provenance, correlation IDs, schema version, etc.) rather than the event payload itself. It is stored and returned unchanged, and is not indexed or matched by queries. It defaults to an empty dict when omitted. Each metadata key and value may be up to 65535 bytes long; appending an event with a longer key or value fails with a validation error.

Include in:

  • Append requests when writing new events to the store.

Included in:

  • SequencedEvent objects when the server responds to read requests.

Matched by:

  • QueryItem during read() and append() operations.

Append Condition

An AppendCondition causes an append request to fail if events match its Query, optionally after a sequence number.

Field Type Description
fail_if_events_match Query Query for conflicting events.
after int|None Sequence number.

Include in:

  • Append requests to define optimistic concurrent control.

To implement a consistency boundary, command handlers can use the same Query used when reading events as the value of fail_if_events_match, and the "head" sequence number received from the read response as the value of after.

Tracking Info

A TrackingInfo instance indicates the source and position of an upstream event.

Field Type Description
source str Upstream sequence name.
position int Upstream sequence number.

Include in:

  • Append requests when recording the results of processing an upstream event.

To implement exactly-once semantics in event-processing components, pull events from an upstream source after the last recorded position, then record the upstream positions of upstream events along with new state that results from processing those events. By processing event sequentially in this way, each event will be processed at least once. And by recording tracking information along with new state, the new state will be recorded at most once. The combination of "at least once" processing and "at most once" recording gives "exactly once" semantics from the point of view of consumers of the recorded state.

Query

A Query defines criteria for selecting events in the event store.

Field Type Description
items list[QueryItem] A list of selection criteria (logical OR).

An Event is selected if any QueryItem matches or the items field is empty.

Include in:

  • Read requests to select events returned by the server.
  • An AppendCondition to select conflicting events.

Query Item

A QueryItem defines a criterion for matching events.

Field Type Description
types list[str] List of event types (logical OR).
tags list[str] List of tags (logical AND).

A QueryItem will match an `Event if:

  • one of its types matches the Event.event_type or its types field is empty; AND
  • all of its tags match one of the Event.tags or its tags field is empty.

Sequenced Event

A SequencedEvent represents a recorded Event along with its assigned sequence number.

Field Type Description
position int The sequence number.
event Event The recorded event.

Included in:

  • Read responses when the server responds to read requests.

Error Handling

The Python client raises Python exceptions on error:

  • Integrity/condition failure: IntegrityError
  • Transport/connection errors: TransportError
  • Authentication failures: AuthenticationError
  • Invalid argument errors: ValueError
  • Other internal errors: RuntimeError or OSError

Your application should catch these as appropriate.

Complete Example

import uuid

from umadb import AppendCondition, Client, Event, IntegrityError, Query, QueryItem

# Connect to the gRPC server (TLS + API key)
client = Client(
    url="http://localhost:50051",
)

# Define a consistency boundary
cb = Query(items=[QueryItem(types=["example"], tags=["tag1", "tag2"])])

# Read events for a decision model
read_response = client.read(query=cb)
for result in read_response:
    print(f"Got event at position {result.position}: {result.event}")

# Remember the last-known position
last_known_position = read_response.head()
print("Last known position is:", last_known_position)

# Create an event with a UUID to enable idempotent append, and some metadata
event = Event(
    event_type="example",
    tags=["tag1", "tag2"],
    data=b"Hello, world!",
    uuid=uuid.uuid4(),
    metadata={"source": "readme", "correlation_id": str(uuid.uuid4())},
)

# Append event within the consistency boundary
condition = AppendCondition(fail_if_events_match=cb, after=last_known_position)
commit_position1 = client.append([event], condition=condition)
print("Appended event at position:", commit_position1)

# Append conflicting event — expect an error
try:
    conflicting_event = Event(
        event_type="example",
        tags=["tag1", "tag2"],
        data=b"Hello, world!",
        uuid=uuid.uuid4(),  # different UUID
    )
    client.append([conflicting_event], condition=condition)
except IntegrityError as e:
    print("Conflicting event was rejected:", e)

# Idempotent retry — same event ID and condition
print("Retrying to append event at position:", last_known_position)
commit_position2 = client.append([event], condition=condition)
assert commit_position1 == commit_position2
print("Append returned same commit position:", commit_position2)

# Subscribe to all events for a projection
for ev in client.subscribe():
    print(f"Processing event at {ev.position}: {ev.event}")
    if ev.position == commit_position2:
        print("Projection has processed new event!")
        break

Example with Tracking

import uuid

from umadb import (
    AppendCondition,
    Client,
    Event,
    IntegrityError,
    Query,
    QueryItem,
    TrackingInfo,
)

# Connect to the gRPC server (TLS + API key)
client = Client(
    url="http://localhost:50051",
)

# Get last processed upstream event position
last_processed_position = client.get_tracking_info("upstream")

# Pull next unprocessed upstream event...
next_upstream_event_position = 1 + (last_processed_position or 0)

# Construct tracking information from next unprocessed event
tracking_info = TrackingInfo("upstream", next_upstream_event_position)

# Define a consistency boundary
cb = Query(items=[QueryItem(types=["example"], tags=["tag1", "tag2"])])

# Read events for a decision model
read_response = client.read(query=cb)
for result in read_response:
    print(f"Got event at position {result.position}: {result.event}")

# Remember the last-known position
last_known_position = read_response.head()
print("Last known position is:", last_known_position)

# Create an event with a UUID to enable idempotent append
event = Event(
    event_type="example",
    tags=["tag1", "tag2"],
    data=b"Hello, world!",
    uuid=uuid.uuid4(),
)

# Append event within the consistency boundary
condition = AppendCondition(fail_if_events_match=cb, after=last_known_position)
commit_position1 = client.append(
    [event], condition=condition, tracking_info=tracking_info
)
print("Appended event at position:", commit_position1)

# Idempotent retry — same event ID and condition
print("Retrying to append event at position:", last_known_position)
commit_position2 = client.append(
    [event], condition=condition, tracking_info=tracking_info
)
assert commit_position1 == commit_position2
print("Append returned same commit position:", commit_position2)

# Check tracking information
assert tracking_info.position == client.get_tracking_info("upstream")

# Unconditional append with conflicting tracking information — expect an error
try:
    conflicting_event = Event(
        event_type="example",
        tags=["tag1", "tag2"],
        data=b"Hello, world!",
        uuid=uuid.uuid4(),  # different UUID
    )
    client.append([conflicting_event], condition=None, tracking_info=tracking_info)
except IntegrityError as e:
    print("Conflicting event was rejected:", e)

Notes

  • Python client is synchronous and blocking; if you need async integration, run client calls in a thread pool or use an async worker that offloads to threads.
  • Event data is binary (bytes). Use a consistent serialization (e.g., JSON serialized to UTF-8 bytes, protobuf, msgpack) for your domain.
  • API keys must match the server configuration.
  • For TLS with self-signed certs, pass ca_path with your root/CA certificate.

Testing

The Python bindings can be tested by running a UmaDB server and executing Python code against it.

License

Licensed under either of:

at your option.

Metadata

Release files for umadb 0.7.8

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

Source distribution (sdist)

Source distribution for umadb 0.7.8
File Size Uploaded
umadb-0.7.8.tar.gz 220.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for umadb 0.7.8
File
umadb-0.7.8-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
umadb-0.7.8-cp310-abi3-win32.whl CPython 3.10 abi3 Windows x86-32 Details
umadb-0.7.8-cp310-abi3-manylinux_2_34_x86_64.whl CPython 3.10 abi3 Linux glibc 2.34+ x86-64 Details
umadb-0.7.8-cp310-abi3-manylinux_2_34_aarch64.whl CPython 3.10 abi3 Linux glibc 2.34+ ARM64 Details
umadb-0.7.8-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
umadb-0.7.8-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 14.4 MB

Release files / umadb-0.7.8.tar.gz

Download URL umadb-0.7.8.tar.gz
Size 220.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fd5d7c74a7504b395f33161e78aba36c7f681b010b447ba72ea5e6550a7cc49c
BLAKE2b-256 checksum
How to use checksums
541fa7cba3676bd517972db971777ed30bf4ec7d047267f25674e9498cb18df9
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-win_amd64.whl

Download URL umadb-0.7.8-cp310-abi3-win_amd64.whl
Size 1.7 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
af94f680ebd2562223de45957d999601aff0a4128734a0ab3a251769a3d49677
BLAKE2b-256 checksum
How to use checksums
b6af6615b3699249e9ac187a2981474c85998bb5a1fcaad07c370f2facc31d51
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-win32.whl

Download URL umadb-0.7.8-cp310-abi3-win32.whl
Size 1.4 MB
Tags CPython 3.10 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
87192d507fe66cb19fd1858101bc34df3607c6f929b7abeb8a62fd8a36f54c8a
BLAKE2b-256 checksum
How to use checksums
d4f2a6d2c13c765a3c2240b7d1d02592be4c5694613a1aa0ca7135a90b41f5fd
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-manylinux_2_34_x86_64.whl

Download URL umadb-0.7.8-cp310-abi3-manylinux_2_34_x86_64.whl
Size 3.0 MB
Tags CPython 3.10 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
dd0ba1edfb0c692234804a4b04cf70908bb48a337318a4c6c7a6ef9edb31fbc0
BLAKE2b-256 checksum
How to use checksums
5359068d9503258969459723f19174869f03500d0b4dbe2d9382d50f863f5675
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-manylinux_2_34_aarch64.whl

Download URL umadb-0.7.8-cp310-abi3-manylinux_2_34_aarch64.whl
Size 2.8 MB
Tags CPython 3.10 Linux glibc 2.34+ ARM64 abi3
SHA-256 checksum
How to use checksums
fea90149a6fdd474c369a8efe45cd861bce2f1478d0048f0f20b1ccb9a76eb15
BLAKE2b-256 checksum
How to use checksums
668f2bed9a6b28209038fa89591c38a948306693a1487c59877c621aee78a851
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-macosx_11_0_arm64.whl

Download URL umadb-0.7.8-cp310-abi3-macosx_11_0_arm64.whl
Size 2.6 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2a0762ee7645af12030aec1e965787ade25676493c2bf2018dbeb38c552a4978
BLAKE2b-256 checksum
How to use checksums
b5051ffaa2f145ae73ea219aeb67e917b889e97a9e0eac234d80fe51af438a93
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 Aug 19, 2026.

Transparency log

Release files / umadb-0.7.8-cp310-abi3-macosx_10_12_x86_64.whl

Download URL umadb-0.7.8-cp310-abi3-macosx_10_12_x86_64.whl
Size 2.8 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
9dbd839a22478215749931ef71099d8d21ad58850d47e1430a8f82fcb3c1cd27
BLAKE2b-256 checksum
How to use checksums
72b34da9072a3b256bc5cf3bfe9e1ab28cc9ee8cb8b894bb521eb1b99fab6eeb
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 Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.8 This release

7 release files

0.7.7

7 release files

0.7.6

7 release files

0.7.5

7 release files

0.7.4

7 release files

0.7.3

7 release files

0.7.2

7 release files

0.7.1

7 release files

0.7.0

7 release files

0.6.14

9 release files

0.6.13

9 release files

0.6.12

9 release files

0.6.11

9 release files

0.6.10

9 release files

0.6.9

9 release files

0.6.8

9 release files

0.6.7

9 release files

0.6.6

9 release files

0.6.5

9 release files

0.6.4

9 release files

0.6.3

9 release files

0.6.2

9 release files

0.6.0

9 release files

0.5.8

9 release files

0.5.7

9 release files

0.5.6

9 release files

0.5.5

9 release files

0.5.4

9 release files

0.5.3

9 release files

0.5.2

9 release files

0.5.1

9 release files

0.5.0

9 release files

0.4.0

9 release files

0.3.3

9 release files

0.3.2

9 release files

0.3.1

9 release files

0.3.0

9 release files

0.2.0

9 release files

0.1.26

9 release files

0.1.25

9 release files

0.1.24

9 release files

0.1.23

9 release files

0.1.22

9 release files

0.1.8

41 release files

0.1.7

41 release files

0.1.6

41 release files

0.1.5

41 release files

0.1.4

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