Skip to main content
Reactor Runtime

Build real-time AI models in Python.

📖 Documentation · 🚀 Quickstart · 🌐 Reactor


Reactor Runtime turns an inference pipeline into a real-time, interactive media and data stream. You write load() and run(); the runtime handles the session lifecycle, the WebRTC media transport, and the wire protocol that connects clients to your model. Viewers watch frames as they are generated and change what the model is doing mid-stream, with no restart and no re-queue.

Highlights

  • 📡 Real-time streaming. Frames reach clients over WebRTC as your model produces them, not after a whole video is done. emit() paces your loop to the rate clients play at, so a model needs no rate limiter of its own.
  • 🎮 Live interaction. Clients send commands mid-generation: change a prompt, move a camera, adjust a parameter. The next frame reflects it.
  • 🔌 No transport code. You never import a WebRTC library, manage a WebSocket, or encode video. The runtime ships its own media engine as a wheel, so a plain Python container is all a model needs.
  • ✅ Typed, validated commands. Declare the commands your model accepts with standard Python types and constraints. The runtime validates every payload before your handler runs and compiles the surface into an OpenAPI schema that drives typed client SDKs.
  • 🔎 Traceable logs. get_logger() writes structured records — readable key=value in a terminal, JSON for a log pipeline. Every record a session writes carries that session's id automatically, so one filter recovers everything a single run logged.
  • 📦 One container, anywhere. The reactor CLI scaffolds a workspace, builds a small image, and runs it locally. The same image deploys to Reactor's GPU cloud unchanged.

How it works

A model is a ReactorModel subclass in model.py. Declare the media it sends, load your weights once, and write the loop that receives or produces frames, data, and more:

from pathlib import Path

from reactor_runtime import InputField, Output, ReactorModel, Video, event


class MyOutput(Output):
    main_video: Video


class MyModel(ReactorModel):
    fps = 24

    def load(self, config_path: Path | None) -> None:
        self.pipe = load_my_pipeline()
        self.prompt = "a sunny meadow"

    @event(name="set_prompt", description="Scene the model renders")
    async def set_prompt(
        self, prompt: str = InputField(default="a sunny meadow", moderate=True)
    ) -> None:
        self.prompt = prompt

    async def run(self) -> None:
        while True:
            await self.connected.wait()
            while self.connected.is_set():
                frame = self.pipe.forward(prompt=self.prompt)
                await self.emit(MyOutput(main_video=frame))

That is a complete model. run() produces frames for as long as someone is watching, and any client can send set_prompt at any time to change what the next frame renders.

Scaffold, build, and run it with the CLI:

reactor init my-model
cd my-model
reactor run

reactor run builds a container with the runtime inside and serves WebRTC signaling on port 8080. Point a browser at it with the JS SDK, or connect from the Reactor Sandbox and watch frames stream immediately.

Log from the same import, passing context as keyword arguments:

from reactor_runtime import get_logger

logger = get_logger(__name__)

logger.info("scene changed", prompt=self.prompt)

Records render as key=value text by default, or as one JSON object per line under REACTOR_LOG_FORMAT=json. While a session is live, its id is stamped on every record, so tracing one run's logs never requires threading an id through your call sites. Every record also carries the lifecycle phase it was written in, at both granularities: state, the session state machine's word, and runtime_state, the coarse word the health endpoint serves — so the logs of one phase — loading weights, a live session, teardown — are filterable by whichever vocabulary you are reading off another surface. The stamp is applied where records are written rather than where they are made, so a plain logging.getLogger(__name__) and the libraries your model imports are covered too.

Install

Everything runs through the reactor CLI. There is nothing to install on your host but the CLI and Docker; the runtime ships inside the image the CLI builds for your workspace.

brew install reactor-team/tools/reactor-cli

Not on macOS, or pinning a release in CI? See Install the CLI.

Learn more

Development

This repository holds the runtime package itself: the authoring interface, the session runner, the media transport, and the wire protocol. To work on it, use mise, which pins the toolchain and forwards every task through a thin make shim:

mise run install      # install deps, generate wire bindings, and git hooks
mise run lint         # ruff check, ruff format --check, and mise.lock drift
mise run format       # apply ruff formatting
mise run typecheck    # ty (strict)
mise run test         # unit tests on the floor Python
mise run test-matrix  # unit tests on every supported Python

License

Licensed under the Apache License, Version 2.0.

Release files for reactor-runtime 3.3.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 reactor-runtime 3.3.1
File Size Uploaded
reactor_runtime-3.3.1.tar.gz 211.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for reactor-runtime 3.3.1
File Interpreter ABI Platform
reactor_runtime-3.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 473.6 kB

Release files / reactor_runtime-3.3.1.tar.gz

Download URL reactor_runtime-3.3.1.tar.gz
Size 211.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1ec8a6d60d81fbaca786bc06f01d077b91d91299e35ff2ec88d594c84101c62d
BLAKE2b-256 checksum
How to use checksums
633f62ea9c06430756c44414300ffc5688846f9e5cb4b817e680403dbb4d867d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / reactor_runtime-3.3.1-py3-none-any.whl

Download URL reactor_runtime-3.3.1-py3-none-any.whl
Size 262.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9813d0f529884490b61b5c6938416e3f60db0c13a0789d574bee79570eb5d15e
BLAKE2b-256 checksum
How to use checksums
da0a66dc0d332c1310f365a669fc300d130867ae883756f1c21f83e441a51487
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

3.6.0

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.3.2

2 release files

This release

3.3.1 This release

2 release files

3.3.0

2 release files

3.2.7

2 release files

3.2.6

2 release files

3.2.5

2 release files

3.2.4

2 release files

3.2.3

2 release files

3.2.2

2 release files

3.2.1

2 release files

3.2.0

2 release files

3.1.2

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.2

2 release files

3.0.1

2 release files

2.10.1

2 release files

2.10.0

2 release files

2.9.4

2 release files

2.9.3

2 release files

2.9.2

2 release files

2.9.1

2 release files

2.9.0

2 release files

2.8.1

2 release files

2.8.0

2 release files

2.7.9

2 release files

2.7.8

2 release files

2.7.7

2 release files

2.7.6

2 release files

2.7.5

2 release files

2.7.4

2 release files

2.7.3

2 release files

2.7.2

2 release files

2.7.1

2 release files

2.7.0

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.7.5

2 release files

1.7.4

2 release files

1.6.3

2 release files

1.6.1

2 release files

1.4.3

2 release files

1.2.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

0.0.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