The part nobody else ships

Streaming SQL you can import

Every other streaming SQL engine is server-shaped: you deploy it, then you talk to it. Ubik's public interface is a C ABI over one shared library, so the engine runs inside your process. Python is the first binding; anything that can call C is the rest.

A durable pipeline, in a notebook

The checkpoint path is the pipeline's identity. The first run creates it, a later run resumes from it, and a crash in between loses no event and double-counts none. Each closed window arrives as an Arrow record batch as it emits.

python
import ubik Q = ("SELECT merchant, TUMBLE(ts, INTERVAL 1 MINUTE) AS w, "     "count(*) AS c FROM orders "     "GROUP BY merchant, TUMBLE(ts, INTERVAL 1 MINUTE)") with ubik.pipeline(Q, from_="kafka://localhost:9092/orders",                   checkpoint="~/.ubik/orders") as p:    for window in p:      # a RecordBatch, as it closes        react(window)

Your DataFrame is a dimension

A host table enters through the Arrow C stream and joins against the stream, including the ASOF versioned pick. Read the result with .arrow(), .df(), .pl() or .rows(). Errors raise with a code, a message and a hint.

python
import pandas, ubik merchants = pandas.DataFrame({"id": [10, 20],                              "region": ["EU", "US"]}) tbl = ubik.stream(    "SELECT m.region, count(*) AS c "    "FROM orders o JOIN merchants m ON o.merchant_id = m.id "    "GROUP BY m.region, TUMBLE(o.event_time, INTERVAL 1 MINUTE)",    from_="kafka://localhost:9092/orders",    tables={"merchants": merchants},).arrow()