Skip to main content

streamator

Backend primitive for streaming structured events and logs from long-running async jobs to a browser UI via SSE — no WebSockets, no custom infrastructure.

Pairs with streamator-react on the frontend.

Install

pip install streamator                    # core only (in-memory)
pip install streamator[fastapi]           # + FastAPI route helpers
pip install streamator[dynamo]            # + DynamoDB backend
pip install streamator[fastapi,dynamo]    # everything

JobEmitter

JobEmitter is the recommended API. It supports structured events, task tracking, cancellation, and result storage — all in one class.

from streamator import JobEmitter
from streamator.fastapi import add_job_routes

add_job_routes(app, prefix="/job")
# GET  /job/{job_id}/stream  → SSE event stream
# GET  /job/{job_id}/result  → stored result (JSON)
# POST /job/{job_id}/cancel  → cancel tracked task

@router.post("/start")
async def start():
    emitter = JobEmitter()

    async def run():
        async with emitter:
            for i in range(1, 6):
                emitter.emit({"event": "progress", "current": i, "total": 5})
                emitter.log(f"Step {i} of 5")
                await do_work()
            emitter.set_result({"steps_completed": 5})
            emitter.log("Done", level="success")

    task = asyncio.create_task(run())
    emitter.track(task)
    return {"job_id": emitter.job_id}

Instance methods

emitter.emit({"event": "progress", "step": 1})  # structured event, t added automatically
emitter.log("Working...", level="info")          # log message shorthand
emitter.track(task)                              # store asyncio.Task for cancellation
emitter.set_result({"count": 42})               # store final result for later retrieval
emitter.close()                                  # idempotent; sends done sentinel

Calling emit() or log() after close() logs a warning and no-ops. Non-JSON-serializable values in emit() are converted to strings automatically.

Class methods

JobEmitter.cancel(job_id)       # cancel tracked task; no-op if unknown
JobEmitter.pop_result(job_id)   # fetch and consume result; None if not ready
JobEmitter.exists(job_id)       # check if job is in registry

Event format on the wire

# emit() — passes through with t added
{"event": "progress", "step": 1, "t": 1.23}

# log() — standard log shape
{"event": "log", "message": "Working...", "level": "info", "t": 1.23}

# close() — terminal sentinel
{"event": "done", "t": 5.67}

Background reaper (optional)

from streamator.emitter import start_reaper

# In FastAPI lifespan:
asyncio.create_task(start_reaper(ttl_seconds=300, interval=60))

Only evicts closed jobs older than ttl_seconds. Off by default.


JobLogger

JobLogger is the simpler API for log-only use cases.

from streamator import JobLogger
from streamator.fastapi import add_log_routes

add_log_routes(app, prefix="/log")   # deprecated — use add_job_routes instead

@router.post("/start")
async def start():
    logger = JobLogger()
    asyncio.create_task(my_job(logger))
    return {"log_job_id": logger.job_id}

add_log_routes still works but emits a DeprecationWarning. Migrate to add_job_routes + JobEmitter when convenient.


Storage backends

Memory (default) — asyncio.Queue, SSE push, zero dependencies, single-process only.

DynamoDB — persists across restarts, readable by polling, distributed-friendly.

emitter = JobEmitter(store="dynamo", table="my-jobs", ttl_days=1)

Log levels

"info" (default) · "success" · "warning" · "error"

Metadata

Release files for streamator 0.2.1

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

Source distribution (sdist)

Source distribution for streamator 0.2.1
File Size Uploaded
streamator-0.2.1.tar.gz 7.5 kB Details

Built distribution (wheel)

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

Total release size: 13.6 kB

Release files / streamator-0.2.1.tar.gz

Download URL streamator-0.2.1.tar.gz
Size 7.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6f7e2a5b084561b065c20cff5550f7ee385a687f5f64d7cf610a2f6f1984bae4
BLAKE2b-256 checksum
How to use checksums
9df52e8f256993b1efbc8003562b6b70cbea9e1113bcb223610270311725e51c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / streamator-0.2.1-py3-none-any.whl

Download URL streamator-0.2.1-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9be7a110d3943af13af11993b7f7b77ae81644a479d1ba872ec8b56827e696f4
BLAKE2b-256 checksum
How to use checksums
3bf69e3fda26f21fb2c049b5fffcc5d08c0d933e11b840c21cf54f0e2db607c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

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