You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(live): add @pipeline decorator for simplified pipeline creation
Add a `@pipeline` decorator that turns a plain function or class into a
fully working live Pipeline subclass — handling frame queues, lifecycle
management, parameter validation, and thread safety automatically.
Includes two example pipelines:
- green_shift: minimal function form (4 lines of user code)
- depth_midas: class form with MiDaS Small depth estimation, demonstrating
prepare_models, on_ready, transform, on_update, and on_stop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
You have two options: the `@pipeline` decorator (recommended) or the raw `Pipeline` interface (full control over frame queuing, batching, and threading).
80
80
81
-
Implement `src/my_pipeline/pipeline/params.py`:
81
+
### Option A: `@pipeline` Decorator (Recommended)
82
+
83
+
The `@pipeline` decorator handles frame queues, lifecycle, threading, and parameter validation automatically.
84
+
85
+
**Function form** — simplest possible pipeline:
82
86
83
87
```python
84
-
from runner.live.pipelines import BaseParams
88
+
# src/my_pipeline/pipeline/pipeline.py
89
+
import torch
90
+
from runner.live.pipelines import pipeline, BaseParams
|`transform(self, frame, params)`| Yes | Every frame |
163
+
|`on_ready(self, **params)`| No | Once on startup |
164
+
|`on_update(self, **params)`| No | When params change mid-stream |
165
+
|`on_stop(self)`| No | On shutdown |
166
+
|`prepare_models(cls)`| No | At build time (model download) |
167
+
168
+
Both `async def` and `def` work. Sync functions automatically run in a thread pool.
169
+
170
+
See [`examples/pipelines/`](../examples/pipelines/) for complete working examples.
171
+
172
+
### Option B: Raw `Pipeline` Interface
91
173
92
-
Implement `src/my_pipeline/pipeline/pipeline.py`:
174
+
For advanced use cases where you need full control over frame queuing, custom batching, or complex threading. Here's the same depth-midas pipeline implemented with the raw interface:
93
175
94
176
```python
177
+
# src/my_pipeline/pipeline/pipeline.py
95
178
import asyncio
96
179
import logging
97
-
180
+
import torch
98
181
from runner.live.pipelines import Pipeline
99
182
from runner.live.trickle import VideoFrame, VideoOutput
For a real-world implementation, see [scope-runner's pipeline](https://github.com/daydreamlive/scope-runner/blob/dec9ecf7e306892df9cfae21759c23fdf15b0510/src/scope_runner/pipeline/pipeline.py#L22).
235
+
For another real-world example, see [scope-runner's pipeline](https://github.com/daydreamlive/scope-runner/blob/dec9ecf7e306892df9cfae21759c23fdf15b0510/src/scope_runner/pipeline/pipeline.py#L22).
236
+
237
+
### Define Parameters (Optional)
238
+
239
+
```python
240
+
# src/my_pipeline/pipeline/params.py
241
+
from runner.live.pipelines import BaseParams
242
+
243
+
classMyPipelineParams(BaseParams):
244
+
# Define your custom fields here
245
+
```
132
246
133
-
### 2.3 Keep Module Exports Minimal
247
+
### Keep Module Exports Minimal
134
248
135
249
> **⚠️ Important**: Do **not** export `Pipeline` or `Params` classes from `__init__.py`. The loader imports these by their full path (`module.path:ClassName`), and re-exporting from `__init__.py` would trigger expensive imports (torch, etc.) when only loading the params class.
136
250
@@ -405,6 +519,19 @@ The orchestrator will route requests to your local runner at `http://localhost:8
405
519
406
520
---
407
521
522
+
## Publishing to the Marketplace
523
+
524
+
Publish your pipeline to make it discoverable on the marketplace. The CLI extracts the parameter schema from your `@pipeline` decorator and registers it automatically.
0 commit comments