Uh oh!
There was an error while loading. Please reload this page.
Conversation
Generated from the Composition API spec, the same way as the Fishjam client. The whip and whep endpoints speak application/sdp, which the generator does not support, so they are absent.
Wraps the generated bindings the way FishjamClient wraps its own, with a register method per input and output variant because the response differs per type. Models are exported from fishjam.composition.
Points Fishjam at a composition and reports the link back on the room. The livestream WHIP and WHEP addresses come with it, since they are derived from the Fishjam URL rather than configured.
A backend that composes a looping movie and a camera published over WHIP into a Fishjam livestream, serving the credentials for both ends over HTTP.
Neither _openapi_client nor _composition_client said what the other did.
There was a problem hiding this comment.
Pull request overview
Adds server-side Composition API support, room track forwarding, livestream endpoints, and an end-to-end composition demo.
Changes:
- Adds generated Composition and renamed Fishjam API clients.
- Exposes composition lifecycle, input/output, renderer, event, and track-forwarding APIs.
- Adds tests and a WHIP/WHEP livestream demo.
Reviewed changes
Copilot reviewed 140 out of 246 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock | Locks demo dependencies. |
pyproject.toml | Adds workspace, generator, lint, and typing configuration. |
scripts.py | Supports generating both API clients. |
openapi-python-client-config.yaml | Renames the Fishjam generated package. |
openapi-python-client-composition-config.yaml | Configures Composition client generation. |
fishjam/__init__.py | Exposes Composition APIs. |
fishjam/utils.py | Builds Composition, WHIP, and WHEP URLs. |
fishjam/errors.py | Adds Composition-specific error mapping. |
fishjam/api/_client.py | Tracks the original Fishjam identifier. |
fishjam/api/_fishjam_client.py | Adds forwarding, livestream URLs, and composition room state. |
fishjam/api/_composition_client.py | Implements the Composition control-plane client. |
fishjam/composition/__init__.py | Publishes Composition models and aliases. |
fishjam/peer/__init__.py | Updates generated-client imports. |
fishjam/recording/__init__.py | Updates generated-client imports. |
fishjam/room/__init__.py | Updates generated-client imports. |
fishjam/_fishjam_openapi_client/** | Renamed and regenerated Fishjam API client modules. |
fishjam/_composition_openapi_client/** | Generated Composition API client modules. |
tests/test_composition.py | Tests Composition operations and models. |
tests/test_track_forwarding.py | Tests forwarding and livestream URL behavior. |
tests/test_room_api.py | Updates generated-client imports. |
tests/fixtures/font.ttf | Adds upload-test fixture. |
examples/room_manager/room_service.py | Updates generated-client import. |
examples/composition/.env.example | Documents demo configuration. |
examples/composition/README.md | Documents the composition demo. |
examples/composition/pyproject.toml | Defines demo dependencies. |
examples/composition/main.py | Runs the demo server lifecycle. |
examples/composition/composition/__init__.py | Defines the demo package. |
examples/composition/composition/app.py | Provides streamer and viewer endpoints. |
examples/composition/composition/config.py | Defines demo configuration and assets. |
examples/composition/composition/composition_service.py | Orchestrates Composition resources. |
examples/composition/composition/fishjam_service.py | Manages the livestream room. |
examples/composition/composition/scene.py | Builds the demo scene. |
Suppressed comments (2)
fishjam/api/_composition_client.py:641
- A missing output on this endpoint is reported as
CompositionNotFoundErrorbecause the default 404 mapping is used. PassOutputNotFoundErrorhere so keyframe requests have the same missing-output semantics as the other output operations.
fishjam/api/_composition_client.py:225 - Wrapping the raw response text in a list makes exceptions for undocumented statuses display messages such as
['gateway failure']. Pass the decoded string directly, consistent withHTTPError.from_response.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
A status outside the standard set raised ValueError from the generated client instead of an HTTPError, and messages were wrapped in a list, so they read as ['gone'] where the Fishjam ones read as text.
Building them at import allocated a room and a composition before startup, and leaked the room when the composition failed.
Description
Adds composition support to the SDK.
CompositionClient, covering the composition control planeforward_room_trackstoFishjamClient, pointing a room's tracks at a compositionRoomMotivation and Context
The Composition API had no server-side client, so anyone creating a composition
hand-rolled HTTP.
Documentation impact
Types of changes
not work as expected)