Skip to main content

bluesky-zerobus

bluesky-zerobus reads Bluesky Jetstream's v2 WebSocket with jetstream-lakehouse and sends normalized events to a Unity Catalog Delta table. The sink uses either the official Databricks Zerobus Python SDK over gRPC or Zerobus' Kafka-compatible producer API. The connector follows live data and resumes from the last locally saved Jetstream sequence after a restart. Archived backfill can be added later.

Prepare Databricks

Zerobus Ingest must be available in your workspace region. Create a table with the same column names and types as the mapper below; change the fully qualified table name as needed:

CREATE TABLE main.bronze.bluesky_events (
  source_id STRING NOT NULL,
  seq BIGINT NOT NULL,
  event_time STRING,
  witnessed_at STRING,
  did STRING,
  kind STRING,
  operation STRING,
  collection STRING,
  rkey STRING,
  cid STRING,
  rev STRING,
  is_resync BOOLEAN,
  record STRING,
  event_payload STRING
) USING DELTA;

record and event_payload contain JSON text. Identity, account, sync, create, update, and delete events all land as separate rows. Build a downstream view or table to fold events into current record state if needed.

Create a Databricks service principal and grant USE CATALOG, USE SCHEMA, SELECT, and MODIFY on the destination. Its application ID and secret belong in .secrets.toml. Follow the Databricks setup guide for the endpoint and grants.

Configure and run

Install dependencies with uv, then copy the example settings into the ignored settings.local.toml. Set your workspace, Zerobus endpoint, table, source ID, and batch limits there. On Azure, the endpoint is https://<workspace-id>.zerobus.<region>.azuredatabricks.net; on AWS, it is https://<workspace-id>.zerobus.<region>.cloud.databricks.com. Get a retained start cursor from the same WebSocket subscription, and set jetstream.start_cursor to the printed number before the first run. Cursor discovery needs no Databricks credentials. Copy the credential template into a local, ignored file:

uv sync --locked
cp settings.toml settings.local.toml
uv run bluesky-zerobus --config settings.local.toml --discover-cursor
# Set jetstream.start_cursor in settings.local.toml to the printed number.
cp credentials.example.toml .secrets.toml
chmod 600 .secrets.toml
uv run bluesky-zerobus --config settings.local.toml --secrets .secrets.toml

Edit .secrets.toml before running. Dynaconf reads the two explicit TOML files. The connector does not load application settings or credentials from environment variables. You can pass other file paths with --config and --secrets.

Choose [sink].type = "grpc" (the default) or "kafka" in the settings TOML. Both sinks use the same [zerobus] endpoint, workspace URL, destination table, and service principal credentials. For a side-by-side comparison, use separate destination tables, pipeline IDs, and checkpoint files so each sink processes its own source window. The Kafka-compatible API is Beta and may need to be enabled in the workspace Previews page.

A new checkpoint requires an explicit start_cursor, so a failure before the first acknowledged batch cannot silently restart from a later live tip. The discovery command subscribes at the current tip, waits for one matching event, and prints its sequence minus one. A saved checkpoint takes precedence on subsequent runs. If the WebSocket can no longer serve a saved cursor, the connector fails rather than skip data. Choose a recovery or archive backfill procedure before changing that checkpoint.

The SQLite checkpoint is stored at pipeline.checkpoint_path, relative to the settings file unless absolute. Put it on persistent storage when deploying. A process lock prevents simultaneous consumers using the same checkpoint. The checkpoint is tied to pipeline.id and a fingerprint of source, filters, source ID, and destination table; changing those settings requires a new pipeline ID. The Databricks credentials are excluded from the fingerprint. source_id identifies a Jetstream serving instance for downstream deduplication.

Stop with SIGINT or SIGTERM. The reader stops, pending rows are flushed, the confirmed cursor is saved, and the Zerobus stream closes.

Set [logging].level in the settings TOML to DEBUG, INFO, WARNING, ERROR, or CRITICAL (INFO by default). This controls only the connector's loggers. Logs go to stderr and report startup, cursor origin, confirmed batches, shutdown, and failure types. Batch confirmation is logged only after the Zerobus acknowledgment and SQLite checkpoint commit. The connector's own log messages omit event payloads and credentials. When running as a Databricks Python task, these messages appear in the task output; Zerobus service activity is available separately in its system tables.

Delivery contract

The source runs in a separate thread with a bounded queue. The WebSocket frame limit matches the configured batch byte limit, and the default queue holds at most 32 events. The producer groups rows by count, UTF-8 byte size, or time. The SDK's ingest_records_offset() queues a batch; flush() waits until Zerobus confirms it is durable. Only then does the connector save the last event sequence in SQLite. The default 4 MiB batch ceiling stays below Zerobus' 10 MB JSON message limit; the ceiling is an estimate of row JSON bytes and leaves room for SDK framing. A record larger than the configured ceiling stops the connector without advancing its cursor.

This provides at-least-once delivery. A crash between Zerobus' confirmation and SQLite's checkpoint commit can repeat a row. Use (source_id, seq) for deduplication downstream. A durability acknowledgment precedes query visibility in the Delta table. See Databricks' acknowledgment guide.

Sink.write_batch(rows) defines the destination contract: it returns only after all rows are durable, or raises. ZerobusGrpcSink uses the official SDK's JSON stream and recovery. ZerobusKafkaSink reuses a long-lived Kafka producer, obtains a fresh table-scoped OAuth token on reconnect, and sends UTF-8 JSON values to a topic named after the full table name. It uses SASL_SSL, OAUTHBEARER, acks=all, and no compression. It checks every produce future before the source checkpoint can advance. A failed batch may have written some rows; replay can therefore duplicate them. Kafka's consumer, admin, and transaction APIs are not available on this endpoint. See the Azure Databricks Kafka-compatible API guide.

Development

uv sync --locked
uv run ruff check .
uv run pytest

Unit tests use a fake WebSocket iterator and sink. A live end-to-end run requires your Jetstream endpoint and a Databricks workspace and is not part of the default test suite.

License

Apache License 2.0. See LICENSE.

Metadata

Release files for bluesky-zerobus 0.1.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 bluesky-zerobus 0.1.0
File Size Uploaded
bluesky_zerobus-0.1.0.tar.gz 21.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bluesky-zerobus 0.1.0
File Interpreter ABI Platform
bluesky_zerobus-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 43.8 kB

Release files / bluesky_zerobus-0.1.0.tar.gz

Download URL bluesky_zerobus-0.1.0.tar.gz
Size 21.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2608e56b7f4a2d1049a301270cd779ed87e86288bf114a12b75308d13224d8dd
BLAKE2b-256 checksum
How to use checksums
1cf3176dc8db767c7636ca37bc855d31f83f793133ad6d305f44c8733d08b7f3
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 Oct 4, 2026.

Transparency log

Release files / bluesky_zerobus-0.1.0-py3-none-any.whl

Download URL bluesky_zerobus-0.1.0-py3-none-any.whl
Size 22.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
992dfbe7f7f1663c314b1301906be382e655d7106733a30255555512bba31a84
BLAKE2b-256 checksum
How to use checksums
663ea33343853e8071971c5a17b993b6e93a06d486e470f4bb2fbf715724e36c
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 Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

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