Jellyfish Python Server SDK

Jellyfish Python Server SDK

CircleCI

Python server SDK for the Jellyfish Media Server.

Read the docs here

Installation

pip install jellyfish-server-sdk

Usage

The SDK exports two main classes for interacting with Jellyfish server: RoomApi and Notifier.

RoomApi wraps http REST api calls, while Notifier is responsible for receiving real-time updates from the server.

RoomApi

Create a RoomApi instance, providing the jellyfish server address and api token

from jellyfish import RoomApi

room_api = RoomApi(server_address="localhost:5002", server_api_token="development")

You can use it to interact with Jellyfish, manage rooms, peers and components

# Create a room
jellyfish_address, room = room_api.create_room(video_codec="h264", webhook_url="http://localhost:5000/webhook")
# '127.0.0.1:5002', Room(components=[], config=RoomConfig(max_peers=None, video_codec=<RoomConfigVideoCodec.H264: 'h264'>, webhook_url='http://localhost:5000/webhook'), id='1d905478-ccfc-44d6-a6e7-8ccb1b38d955', peers=[])

# Add peer to the room
from jellyfish import PeerOptionsWebRTC

peer_token, peer_webrtc = room_api.add_peer(room.id, options=PeerOptionsWebRTC())
# 'M8TUGhj-L11KpyG-2zBPIo', Peer(id='b1232c7e-c969-4450-acdf-ea24f3cdd7f6', status=<PeerStatus.DISCONNECTED: 'disconnected'>, type='webrtc')

# Add component to the room
from jellyfish import ComponentOptionsHLS

component_hls = room_api.add_component(room.id, options=ComponentOptionsHLS())
# ComponentHLS(id='5f062447-a9f7-45ed-8d1b-511f77dc78ae', properties=ComponentPropertiesHLS(low_latency=False, persistent=False, playable=False, subscribe_mode=<ComponentPropertiesHLSSubscribeMode.AUTO: 'auto'>, target_window_duration=None), type='hls')

All methods in RoomApi may raise one of the exceptions deriving from jellyfish.errors.HTTPError. They are defined in jellyfish.errors.

Notifier

Notifier allows for receiving real-time updates from the Jellyfish Server.

You can read more about notifications in the Jellyfish Docs.

Create Notifier instance

from jellyfish import Notifier

notifier = Notifier(server_address='localhost:5002', server_api_token='development')

Then define handlers for incoming messages

@notifier.on_server_notification
def handle_notification(server_notification):
    print(f'Received a notification: {server_notification}')

@notifier.on_metrics
def handle_metrics(metrics_report):
    print(f'Received WebRTC metrics: {metrics_report}')

After that you can start the notifier

async def test_notifier():
    notifier_task = asyncio.create_task(notifier.connect())

    # Wait for notifier to be ready to receive messages
    await notifier.wait_ready()

    # Create a room to trigger a server notification
    room_api = RoomApi()
    room_api.create_room()

    await notifier_task

asyncio.run(test_notifier())

# Received a notification: ServerMessageRoomCreated(room_id='69a3fd1a-6a4d-47bc-ae54-0c72b0d05e29')
# Received WebRTC metrics: ServerMessageMetricsReport(metrics='{}')

Cluster of Jellyfishes

The cluster of jellyfishes has got embedded load balancer, which means that a new room will be created on jellyfish with the least usage. At the moment to modify this specific room you must communicate with the jellyfish on which this room was created.

room_api = RoomApi(server_address='localhost:5002')

# Create a room to trigger a server notification with h264 as a codec,
# that allow to use HLS.
address, room = room_api.create_room(video_codec="h264")

# Create new room api with returned jellyfish address as a room could be
# created on a different jellyfish instance
# (if you communicate with a cluster of jellyfishes)
new_room_api = RoomApi(server_address=address)

# Add HLS component with manual subscribe mode, we use here `new_room_api` as we are sure that this API refers to the jellyfish on which this room was created.
_hls_component = new_room_api.add_component(
    room.id,
    ComponentOptionsHLS(subscribe_mode=ComponentOptionsHLSSubscribeMode.MANUAL),
)

Testing

You can test the SDK by running

poetry run ci_test

In local development you can use

poetry run local_test

Format & Lint

You can format code by running

poetry run format

You can check linter by running

poetry run lint

Copyright 2023, Software Mansion

Software Mansion

Licensed under the Apache License, Version 2.0

 1"""
 2    .. include:: ../README.md
 3"""
 4
 5# pylint: disable=locally-disabled, no-name-in-module, import-error
 6
 7# Exceptions and Server Messages
 8from jellyfish import errors, events
 9
10# Models
11from jellyfish._openapi_client.models import (
12    ComponentFile,
13    ComponentHLS,
14    ComponentOptionsFile,
15    ComponentOptionsHLS,
16    ComponentOptionsHLSSubscribeMode,
17    ComponentOptionsRecording,
18    ComponentOptionsRecordingSubscribeMode,
19    ComponentOptionsRTSP,
20    ComponentOptionsSIP,
21    ComponentPropertiesFile,
22    ComponentPropertiesHLS,
23    ComponentPropertiesHLSSubscribeMode,
24    ComponentPropertiesRecording,
25    ComponentPropertiesRecordingSubscribeMode,
26    ComponentPropertiesRTSP,
27    ComponentPropertiesSIP,
28    ComponentPropertiesSIPSIPCredentials,
29    ComponentRecording,
30    ComponentRTSP,
31    ComponentSIP,
32    Peer,
33    PeerOptionsWebRTC,
34    PeerStatus,
35    Room,
36    RoomConfig,
37    RoomConfigVideoCodec,
38    S3Credentials,
39    SIPCredentials,
40)
41
42# API
43from jellyfish._webhook_notifier import receive_binary
44from jellyfish._ws_notifier import Notifier
45from jellyfish.api._recording_api import RecordingApi
46from jellyfish.api._room_api import RoomApi
47
48__all__ = [
49    "RoomApi",
50    "RecordingApi",
51    "Notifier",
52    "receive_binary",
53    "Room",
54    "RoomConfig",
55    "RoomConfigVideoCodec",
56    "Peer",
57    "PeerOptionsWebRTC",
58    "PeerStatus",
59    "ComponentHLS",
60    "ComponentOptionsHLS",
61    "ComponentOptionsHLSSubscribeMode",
62    "ComponentPropertiesHLS",
63    "ComponentPropertiesHLSSubscribeMode",
64    "ComponentSIP",
65    "ComponentOptionsSIP",
66    "ComponentPropertiesSIP",
67    "ComponentPropertiesSIPSIPCredentials",
68    "ComponentFile",
69    "ComponentRTSP",
70    "ComponentOptionsRTSP",
71    "ComponentPropertiesRTSP",
72    "ComponentFile",
73    "ComponentOptionsFile",
74    "ComponentPropertiesFile",
75    "events",
76    "errors",
77    "SIPCredentials",
78    "ComponentRecording",
79    "ComponentOptionsRecording",
80    "ComponentOptionsRecordingSubscribeMode",
81    "ComponentPropertiesRecording",
82    "ComponentPropertiesRecordingSubscribeMode",
83    "S3Credentials",
84]
85__docformat__ = "restructuredtext"
class RoomApi(jellyfish.api._base_api.BaseApi):
 43class RoomApi(BaseApi):
 44    """Allows for managing rooms"""
 45
 46    def __init__(
 47        self,
 48        server_address: str = "localhost:5002",
 49        server_api_token: str = "development",
 50        secure: bool = False,
 51    ):
 52        """
 53        Create RoomApi instance, providing the jellyfish address and api token.
 54        Set secure to `True` for `https` and `False` for `http` connection (default).
 55        """
 56        super().__init__(
 57            server_address=server_address,
 58            server_api_token=server_api_token,
 59            secure=secure,
 60        )
 61
 62    def create_room(
 63        self,
 64        room_id: str = None,
 65        max_peers: int = None,
 66        video_codec: Literal["h264", "vp8"] = None,
 67        webhook_url: str = None,
 68        peerless_purge_timeout: int = None,
 69        peer_disconnected_timeout: int = None,
 70    ) -> Tuple[str, Room]:
 71        """
 72        Creates a new room
 73
 74        Returns a tuple (`jellyfish_address`, `Room`) - the address of the Jellyfish
 75        in which the room has been created and the created `Room`
 76
 77        The returned address may be different from the current `RoomApi` instance.
 78        In such case, a new `RoomApi` instance has to be created using
 79        the returned address in order to interact with the room.
 80        """
 81
 82        if video_codec is not None:
 83            video_codec = RoomConfigVideoCodec(video_codec)
 84        else:
 85            video_codec = None
 86
 87        room_config = RoomConfig(
 88            room_id=room_id,
 89            max_peers=max_peers,
 90            video_codec=video_codec,
 91            webhook_url=webhook_url,
 92            peerless_purge_timeout=peerless_purge_timeout,
 93            peer_disconnected_timeout=peer_disconnected_timeout,
 94        )
 95
 96        resp = self._request(room_create_room, json_body=room_config)
 97        return (resp.data.jellyfish_address, resp.data.room)
 98
 99    def delete_room(self, room_id: str) -> None:
100        """Deletes a room"""
101
102        return self._request(room_delete_room, room_id=room_id)
103
104    def get_all_rooms(self) -> list:
105        """Returns list of all rooms"""
106
107        return self._request(room_get_all_rooms).data
108
109    def get_room(self, room_id: str) -> Room:
110        """Returns room with the given id"""
111
112        return self._request(room_get_room, room_id=room_id).data
113
114    def add_peer(
115        self, room_id: str, options: PeerOptionsWebRTC
116    ) -> PeerDetailsResponseData:
117        """
118        Creates peer in the room
119
120        Currently only `webrtc` peer is supported
121
122        Returns a tuple (`peer_token`, `Peer`) - the token needed by Peer
123        to authenticate to Jellyfish and the new `Peer`.
124
125        The possible options to pass for peer are `PeerOptionsWebRTC`.
126        """
127
128        peer_type = "webrtc"
129        json_body = AddPeerJsonBody(type=peer_type, options=options)
130
131        resp = self._request(room_add_peer, room_id=room_id, json_body=json_body)
132        return PeerDetailsResponseData(
133            peer=resp.data.peer,
134            token=resp.data.token,
135            peer_websocket_url=resp.data.peer_websocket_url,
136        )
137
138    def delete_peer(self, room_id: str, peer_id: str) -> None:
139        """Deletes peer"""
140
141        return self._request(room_delete_peer, id=peer_id, room_id=room_id)
142
143    def add_component(
144        self,
145        room_id: str,
146        options: Union[
147            ComponentOptionsFile,
148            ComponentOptionsHLS,
149            ComponentOptionsRecording,
150            ComponentOptionsRTSP,
151            ComponentOptionsSIP,
152        ],
153    ) -> Union[
154        ComponentFile, ComponentHLS, ComponentRecording, ComponentRTSP, ComponentSIP
155    ]:
156        """
157        Creates component in the room.
158        Currently there are 4 different components:
159        * File Component for which the options are `ComponentOptionsFile`
160        * HLS Component which options are `ComponentOptionsHLS`
161        * Recording Component which options are `ComponentOptionsRecording`
162        * RTSP Component which options are `ComponentOptionsRTSP`
163        * SIP Component which options are `ComponentOptionsSIP`
164        """
165
166        if isinstance(options, ComponentOptionsFile):
167            component_type = "file"
168        elif isinstance(options, ComponentOptionsHLS):
169            component_type = "hls"
170        elif isinstance(options, ComponentOptionsRecording):
171            component_type = "recording"
172        elif isinstance(options, ComponentOptionsRTSP):
173            component_type = "rtsp"
174        elif isinstance(options, ComponentOptionsSIP):
175            component_type = "sip"
176        else:
177            raise ValueError(
178                "options must be ComponentOptionsFile, ComponentOptionsHLS,"
179                "ComponentOptionsRTSP, ComponentOptionsRecording or ComponentOptionsSIP"
180            )
181
182        json_body = AddComponentJsonBody(type=component_type, options=options)
183
184        return self._request(
185            room_add_component, room_id=room_id, json_body=json_body
186        ).data
187
188    def delete_component(self, room_id: str, component_id: str) -> None:
189        """Deletes component"""
190
191        return self._request(room_delete_component, id=component_id, room_id=room_id)
192
193    def subscribe(self, room_id: str, component_id: str, origins: List[str]):
194        """
195        In order to subscribe the component to peers/components,
196        the component should be initialized with the subscribe_mode set to manual.
197        This mode proves beneficial when you do not wish to record or stream
198        all the available streams within a room.
199        It allows for selective addition instead –
200        you can manually select specific streams.
201        For instance, you could opt to record only the stream of an event's host.
202        """
203
204        return self._request(
205            subscribe_to,
206            room_id=room_id,
207            component_id=component_id,
208            json_body=SubscriptionConfig(origins=origins),
209        )
210
211    def sip_dial(self, room_id: str, component_id: str, phone_number: str):
212        """
213        Starts a phone call from a specified component to a provided phone number.
214
215        This is asynchronous operation.
216        In case of providing incorrect phone number you will receive
217        notification `ComponentCrashed`.
218        """
219
220        return self._request(
221            sip_dial,
222            room_id=room_id,
223            component_id=component_id,
224            json_body=DialConfig(phone_number=phone_number),
225        )
226
227    def sip_end_call(self, room_id: str, component_id: str):
228        """
229        End a phone call on a specified SIP component.
230
231        This is asynchronous operation.
232        """
233
234        return self._request(
235            sip_end_call,
236            room_id=room_id,
237            component_id=component_id,
238        )

Allows for managing rooms

RoomApi( server_address: str = 'localhost:5002', server_api_token: str = 'development', secure: bool = False)
46    def __init__(
47        self,
48        server_address: str = "localhost:5002",
49        server_api_token: str = "development",
50        secure: bool = False,
51    ):
52        """
53        Create RoomApi instance, providing the jellyfish address and api token.
54        Set secure to `True` for `https` and `False` for `http` connection (default).
55        """
56        super().__init__(
57            server_address=server_address,
58            server_api_token=server_api_token,
59            secure=secure,
60        )

Create RoomApi instance, providing the jellyfish address and api token. Set secure to True for https and False for http connection (default).

def create_room( self, room_id: str = None, max_peers: int = None, video_codec: Literal['h264', 'vp8'] = None, webhook_url: str = None, peerless_purge_timeout: int = None, peer_disconnected_timeout: int = None) -> Tuple[str, Room]:
62    def create_room(
63        self,
64        room_id: str = None,
65        max_peers: int = None,
66        video_codec: Literal["h264", "vp8"] = None,
67        webhook_url: str = None,
68        peerless_purge_timeout: int = None,
69        peer_disconnected_timeout: int = None,
70    ) -> Tuple[str, Room]:
71        """
72        Creates a new room
73
74        Returns a tuple (`jellyfish_address`, `Room`) - the address of the Jellyfish
75        in which the room has been created and the created `Room`
76
77        The returned address may be different from the current `RoomApi` instance.
78        In such case, a new `RoomApi` instance has to be created using
79        the returned address in order to interact with the room.
80        """
81
82        if video_codec is not None:
83            video_codec = RoomConfigVideoCodec(video_codec)
84        else:
85            video_codec = None
86
87        room_config = RoomConfig(
88            room_id=room_id,
89            max_peers=max_peers,
90            video_codec=video_codec,
91            webhook_url=webhook_url,
92            peerless_purge_timeout=peerless_purge_timeout,
93            peer_disconnected_timeout=peer_disconnected_timeout,
94        )
95
96        resp = self._request(room_create_room, json_body=room_config)
97        return (resp.data.jellyfish_address, resp.data.room)

Creates a new room

Returns a tuple (jellyfish_address, Room) - the address of the Jellyfish in which the room has been created and the created Room

The returned address may be different from the current RoomApi instance. In such case, a new RoomApi instance has to be created using the returned address in order to interact with the room.

def delete_room(self, room_id: str) -> None:
 99    def delete_room(self, room_id: str) -> None:
100        """Deletes a room"""
101
102        return self._request(room_delete_room, room_id=room_id)

Deletes a room

def get_all_rooms(self) -> list:
104    def get_all_rooms(self) -> list:
105        """Returns list of all rooms"""
106
107        return self._request(room_get_all_rooms).data

Returns list of all rooms

def get_room(self, room_id: str) -> Room:
109    def get_room(self, room_id: str) -> Room:
110        """Returns room with the given id"""
111
112        return self._request(room_get_room, room_id=room_id).data

Returns room with the given id

def add_peer( self, room_id: str, options: PeerOptionsWebRTC) -> jellyfish._openapi_client.models.peer_details_response_data.PeerDetailsResponseData:
114    def add_peer(
115        self, room_id: str, options: PeerOptionsWebRTC
116    ) -> PeerDetailsResponseData:
117        """
118        Creates peer in the room
119
120        Currently only `webrtc` peer is supported
121
122        Returns a tuple (`peer_token`, `Peer`) - the token needed by Peer
123        to authenticate to Jellyfish and the new `Peer`.
124
125        The possible options to pass for peer are `PeerOptionsWebRTC`.
126        """
127
128        peer_type = "webrtc"
129        json_body = AddPeerJsonBody(type=peer_type, options=options)
130
131        resp = self._request(room_add_peer, room_id=room_id, json_body=json_body)
132        return PeerDetailsResponseData(
133            peer=resp.data.peer,
134            token=resp.data.token,
135            peer_websocket_url=resp.data.peer_websocket_url,
136        )

Creates peer in the room

Currently only webrtc peer is supported

Returns a tuple (peer_token, Peer) - the token needed by Peer to authenticate to Jellyfish and the new Peer.

The possible options to pass for peer are PeerOptionsWebRTC.

def delete_peer(self, room_id: str, peer_id: str) -> None:
138    def delete_peer(self, room_id: str, peer_id: str) -> None:
139        """Deletes peer"""
140
141        return self._request(room_delete_peer, id=peer_id, room_id=room_id)

Deletes peer

143    def add_component(
144        self,
145        room_id: str,
146        options: Union[
147            ComponentOptionsFile,
148            ComponentOptionsHLS,
149            ComponentOptionsRecording,
150            ComponentOptionsRTSP,
151            ComponentOptionsSIP,
152        ],
153    ) -> Union[
154        ComponentFile, ComponentHLS, ComponentRecording, ComponentRTSP, ComponentSIP
155    ]:
156        """
157        Creates component in the room.
158        Currently there are 4 different components:
159        * File Component for which the options are `ComponentOptionsFile`
160        * HLS Component which options are `ComponentOptionsHLS`
161        * Recording Component which options are `ComponentOptionsRecording`
162        * RTSP Component which options are `ComponentOptionsRTSP`
163        * SIP Component which options are `ComponentOptionsSIP`
164        """
165
166        if isinstance(options, ComponentOptionsFile):
167            component_type = "file"
168        elif isinstance(options, ComponentOptionsHLS):
169            component_type = "hls"
170        elif isinstance(options, ComponentOptionsRecording):
171            component_type = "recording"
172        elif isinstance(options, ComponentOptionsRTSP):
173            component_type = "rtsp"
174        elif isinstance(options, ComponentOptionsSIP):
175            component_type = "sip"
176        else:
177            raise ValueError(
178                "options must be ComponentOptionsFile, ComponentOptionsHLS,"
179                "ComponentOptionsRTSP, ComponentOptionsRecording or ComponentOptionsSIP"
180            )
181
182        json_body = AddComponentJsonBody(type=component_type, options=options)
183
184        return self._request(
185            room_add_component, room_id=room_id, json_body=json_body
186        ).data

Creates component in the room. Currently there are 4 different components:

def delete_component(self, room_id: str, component_id: str) -> None:
188    def delete_component(self, room_id: str, component_id: str) -> None:
189        """Deletes component"""
190
191        return self._request(room_delete_component, id=component_id, room_id=room_id)

Deletes component

def subscribe(self, room_id: str, component_id: str, origins: List[str]):
193    def subscribe(self, room_id: str, component_id: str, origins: List[str]):
194        """
195        In order to subscribe the component to peers/components,
196        the component should be initialized with the subscribe_mode set to manual.
197        This mode proves beneficial when you do not wish to record or stream
198        all the available streams within a room.
199        It allows for selective addition instead –
200        you can manually select specific streams.
201        For instance, you could opt to record only the stream of an event's host.
202        """
203
204        return self._request(
205            subscribe_to,
206            room_id=room_id,
207            component_id=component_id,
208            json_body=SubscriptionConfig(origins=origins),
209        )

In order to subscribe the component to peers/components, the component should be initialized with the subscribe_mode set to manual. This mode proves beneficial when you do not wish to record or stream all the available streams within a room. It allows for selective addition instead – you can manually select specific streams. For instance, you could opt to record only the stream of an event's host.

def sip_dial(self, room_id: str, component_id: str, phone_number: str):
211    def sip_dial(self, room_id: str, component_id: str, phone_number: str):
212        """
213        Starts a phone call from a specified component to a provided phone number.
214
215        This is asynchronous operation.
216        In case of providing incorrect phone number you will receive
217        notification `ComponentCrashed`.
218        """
219
220        return self._request(
221            sip_dial,
222            room_id=room_id,
223            component_id=component_id,
224            json_body=DialConfig(phone_number=phone_number),
225        )

Starts a phone call from a specified component to a provided phone number.

This is asynchronous operation. In case of providing incorrect phone number you will receive notification ComponentCrashed.

def sip_end_call(self, room_id: str, component_id: str):
227    def sip_end_call(self, room_id: str, component_id: str):
228        """
229        End a phone call on a specified SIP component.
230
231        This is asynchronous operation.
232        """
233
234        return self._request(
235            sip_end_call,
236            room_id=room_id,
237            component_id=component_id,
238        )

End a phone call on a specified SIP component.

This is asynchronous operation.

Inherited Members
jellyfish.api._base_api.BaseApi
client
class RecordingApi(jellyfish.api._base_api.BaseApi):
10class RecordingApi(BaseApi):
11    """Allows for managing recordings"""
12
13    def __init__(
14        self,
15        server_address: str = "localhost:5002",
16        server_api_token: str = "development",
17        secure: bool = False,
18    ):
19        """
20        Create RecordingApi instance, providing the jellyfish address and api token.
21        Set secure to `True` for `https` and `False` for `http` connection (default).
22        """
23
24        super().__init__(
25            server_address=server_address,
26            server_api_token=server_api_token,
27            secure=secure,
28        )
29
30    def get_list(self) -> list:
31        """Returns a list of available recordings"""
32
33        return self._request(get_recordings).data
34
35    def delete(self, recording_id: str):
36        """Deletes recording with given id"""
37
38        return self._request(delete_recording, recording_id=recording_id)

Allows for managing recordings

RecordingApi( server_address: str = 'localhost:5002', server_api_token: str = 'development', secure: bool = False)
13    def __init__(
14        self,
15        server_address: str = "localhost:5002",
16        server_api_token: str = "development",
17        secure: bool = False,
18    ):
19        """
20        Create RecordingApi instance, providing the jellyfish address and api token.
21        Set secure to `True` for `https` and `False` for `http` connection (default).
22        """
23
24        super().__init__(
25            server_address=server_address,
26            server_api_token=server_api_token,
27            secure=secure,
28        )

Create RecordingApi instance, providing the jellyfish address and api token. Set secure to True for https and False for http connection (default).

def get_list(self) -> list:
30    def get_list(self) -> list:
31        """Returns a list of available recordings"""
32
33        return self._request(get_recordings).data

Returns a list of available recordings

def delete(self, recording_id: str):
35    def delete(self, recording_id: str):
36        """Deletes recording with given id"""
37
38        return self._request(delete_recording, recording_id=recording_id)

Deletes recording with given id

Inherited Members
jellyfish.api._base_api.BaseApi
client
class Notifier:
 24class Notifier:
 25    """
 26    Allows for receiving WebSocket messages from Jellyfish.
 27    """
 28
 29    def __init__(
 30        self,
 31        server_address: str = "localhost:5002",
 32        server_api_token: str = "development",
 33        secure: bool = False,
 34    ):
 35        """
 36        Create Notifier instance, providing the jellyfish address and api token.
 37        Set secure to `True` for `wss` and `False` for `ws` connection (default).
 38        """
 39
 40        protocol = "wss" if secure else "ws"
 41        self._server_address = f"{protocol}://{server_address}/socket/server/websocket"
 42        self._server_api_token = server_api_token
 43        self._websocket = None
 44        self._ready = False
 45
 46        self._ready_event: asyncio.Event = None
 47
 48        self._notification_handler: Callable = None
 49        self._metrics_handler: Callable = None
 50
 51    def on_server_notification(self, handler: Callable[[Any], None]):
 52        """
 53        Decorator used for defining handler for ServerNotifications
 54        i.e. all messages other than `ServerMessageMetricsReport`.
 55        """
 56        self._notification_handler = handler
 57        return handler
 58
 59    def on_metrics(self, handler: Callable[[ServerMessageMetricsReport], None]):
 60        """
 61        Decorator used for defining handler for `ServerMessageMetricsReport`.
 62        """
 63        self._metrics_handler = handler
 64        return handler
 65
 66    async def connect(self):
 67        """
 68        A coroutine which connects Notifier to Jellyfish and listens for all incoming
 69        messages from the Jellyfish.
 70
 71        It runs until the connection isn't closed.
 72
 73        The incoming messages are handled by the functions defined using the
 74        `on_server_notification` and `on_metrics` decorators.
 75
 76        The handlers have to be defined before calling `connect`,
 77        otherwise the messages won't be received.
 78        """
 79        async with client.connect(self._server_address) as websocket:
 80            try:
 81                self._websocket = websocket
 82                await self._authenticate()
 83
 84                if self._notification_handler:
 85                    await self._subscribe_event(
 86                        event=ServerMessageEventType.EVENT_TYPE_SERVER_NOTIFICATION
 87                    )
 88
 89                if self._metrics_handler:
 90                    await self._subscribe_event(
 91                        event=ServerMessageEventType.EVENT_TYPE_METRICS
 92                    )
 93
 94                self._ready = True
 95                if self._ready_event:
 96                    self._ready_event.set()
 97
 98                await self._receive_loop()
 99            finally:
100                self._websocket = None
101
102    async def wait_ready(self) -> True:
103        """
104        Waits until the notifier is connected and authenticated to Jellyfish.
105
106        If already connected, returns `True` immediately.
107        """
108        if self._ready:
109            return True
110
111        if self._ready_event is None:
112            self._ready_event = asyncio.Event()
113
114        await self._ready_event.wait()
115
116    async def _authenticate(self):
117        msg = ServerMessage(
118            auth_request=ServerMessageAuthRequest(token=self._server_api_token)
119        )
120        await self._websocket.send(bytes(msg))
121
122        try:
123            message = await self._websocket.recv()
124        except ConnectionClosed as exception:
125            if "invalid token" in str(exception):
126                raise RuntimeError("Invalid server_api_token") from exception
127            raise
128
129        message = ServerMessage().parse(message)
130
131        _type, message = betterproto.which_one_of(message, "content")
132        assert isinstance(message, ServerMessageAuthenticated)
133
134    async def _receive_loop(self):
135        while True:
136            message = await self._websocket.recv()
137            message = ServerMessage().parse(message)
138            _which, message = betterproto.which_one_of(message, "content")
139
140            if isinstance(message, ServerMessageMetricsReport):
141                self._metrics_handler(message)
142            else:
143                self._notification_handler(message)
144
145    async def _subscribe_event(self, event: ServerMessageEventType):
146        request = ServerMessage(subscribe_request=ServerMessageSubscribeRequest(event))
147
148        await self._websocket.send(bytes(request))
149        message = await self._websocket.recv()
150        message = ServerMessage().parse(message)
151        _which, message = betterproto.which_one_of(message, "content")
152        assert isinstance(message, ServerMessageSubscribeResponse)

Allows for receiving WebSocket messages from Jellyfish.

Notifier( server_address: str = 'localhost:5002', server_api_token: str = 'development', secure: bool = False)
29    def __init__(
30        self,
31        server_address: str = "localhost:5002",
32        server_api_token: str = "development",
33        secure: bool = False,
34    ):
35        """
36        Create Notifier instance, providing the jellyfish address and api token.
37        Set secure to `True` for `wss` and `False` for `ws` connection (default).
38        """
39
40        protocol = "wss" if secure else "ws"
41        self._server_address = f"{protocol}://{server_address}/socket/server/websocket"
42        self._server_api_token = server_api_token
43        self._websocket = None
44        self._ready = False
45
46        self._ready_event: asyncio.Event = None
47
48        self._notification_handler: Callable = None
49        self._metrics_handler: Callable = None

Create Notifier instance, providing the jellyfish address and api token. Set secure to True for wss and False for ws connection (default).

def on_server_notification(self, handler: Callable[[Any], NoneType]):
51    def on_server_notification(self, handler: Callable[[Any], None]):
52        """
53        Decorator used for defining handler for ServerNotifications
54        i.e. all messages other than `ServerMessageMetricsReport`.
55        """
56        self._notification_handler = handler
57        return handler

Decorator used for defining handler for ServerNotifications i.e. all messages other than ServerMessageMetricsReport.

def on_metrics( self, handler: Callable[[jellyfish.events._protos.jellyfish.ServerMessageMetricsReport], NoneType]):
59    def on_metrics(self, handler: Callable[[ServerMessageMetricsReport], None]):
60        """
61        Decorator used for defining handler for `ServerMessageMetricsReport`.
62        """
63        self._metrics_handler = handler
64        return handler

Decorator used for defining handler for ServerMessageMetricsReport.

async def connect(self):
 66    async def connect(self):
 67        """
 68        A coroutine which connects Notifier to Jellyfish and listens for all incoming
 69        messages from the Jellyfish.
 70
 71        It runs until the connection isn't closed.
 72
 73        The incoming messages are handled by the functions defined using the
 74        `on_server_notification` and `on_metrics` decorators.
 75
 76        The handlers have to be defined before calling `connect`,
 77        otherwise the messages won't be received.
 78        """
 79        async with client.connect(self._server_address) as websocket:
 80            try:
 81                self._websocket = websocket
 82                await self._authenticate()
 83
 84                if self._notification_handler:
 85                    await self._subscribe_event(
 86                        event=ServerMessageEventType.EVENT_TYPE_SERVER_NOTIFICATION
 87                    )
 88
 89                if self._metrics_handler:
 90                    await self._subscribe_event(
 91                        event=ServerMessageEventType.EVENT_TYPE_METRICS
 92                    )
 93
 94                self._ready = True
 95                if self._ready_event:
 96                    self._ready_event.set()
 97
 98                await self._receive_loop()
 99            finally:
100                self._websocket = None

A coroutine which connects Notifier to Jellyfish and listens for all incoming messages from the Jellyfish.

It runs until the connection isn't closed.

The incoming messages are handled by the functions defined using the on_server_notification and on_metrics decorators.

The handlers have to be defined before calling connect, otherwise the messages won't be received.

async def wait_ready(self) -> True:
102    async def wait_ready(self) -> True:
103        """
104        Waits until the notifier is connected and authenticated to Jellyfish.
105
106        If already connected, returns `True` immediately.
107        """
108        if self._ready:
109            return True
110
111        if self._ready_event is None:
112            self._ready_event = asyncio.Event()
113
114        await self._ready_event.wait()

Waits until the notifier is connected and authenticated to Jellyfish.

If already connected, returns True immediately.

def receive_binary(binary: bytes) -> betterproto.Message:
12def receive_binary(binary: bytes) -> betterproto.Message:
13    """
14    Transform received protobuf notification to adequate notification instance.
15
16    The available notifications are listed in `jellyfish.events` module.
17    """
18    message = ServerMessage().parse(binary)
19    _which, message = betterproto.which_one_of(message, "content")
20    return message

Transform received protobuf notification to adequate notification instance.

The available notifications are listed in jellyfish.events module.

class Room:
 28@_attrs_define
 29class Room:
 30    """Description of the room state"""
 31
 32    components: List[
 33        Union[
 34            "ComponentFile",
 35            "ComponentHLS",
 36            "ComponentRTSP",
 37            "ComponentRecording",
 38            "ComponentSIP",
 39        ]
 40    ]
 41    """List of all components"""
 42    config: "RoomConfig"
 43    """Room configuration"""
 44    id: str
 45    """Room ID"""
 46    peers: List["Peer"]
 47    """List of all peers"""
 48    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 49    """@private"""
 50
 51    def to_dict(self) -> Dict[str, Any]:
 52        """@private"""
 53        from ..models.component_file import ComponentFile
 54        from ..models.component_hls import ComponentHLS
 55        from ..models.component_rtsp import ComponentRTSP
 56        from ..models.component_sip import ComponentSIP
 57
 58        components = []
 59        for components_item_data in self.components:
 60            components_item: Dict[str, Any]
 61
 62            if isinstance(components_item_data, ComponentHLS):
 63                components_item = components_item_data.to_dict()
 64
 65            elif isinstance(components_item_data, ComponentRTSP):
 66                components_item = components_item_data.to_dict()
 67
 68            elif isinstance(components_item_data, ComponentFile):
 69                components_item = components_item_data.to_dict()
 70
 71            elif isinstance(components_item_data, ComponentSIP):
 72                components_item = components_item_data.to_dict()
 73
 74            else:
 75                components_item = components_item_data.to_dict()
 76
 77            components.append(components_item)
 78
 79        config = self.config.to_dict()
 80
 81        id = self.id
 82        peers = []
 83        for peers_item_data in self.peers:
 84            peers_item = peers_item_data.to_dict()
 85
 86            peers.append(peers_item)
 87
 88        field_dict: Dict[str, Any] = {}
 89        field_dict.update(self.additional_properties)
 90        field_dict.update(
 91            {
 92                "components": components,
 93                "config": config,
 94                "id": id,
 95                "peers": peers,
 96            }
 97        )
 98
 99        return field_dict
100
101    @classmethod
102    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
103        """@private"""
104        from ..models.component_file import ComponentFile
105        from ..models.component_hls import ComponentHLS
106        from ..models.component_recording import ComponentRecording
107        from ..models.component_rtsp import ComponentRTSP
108        from ..models.component_sip import ComponentSIP
109        from ..models.peer import Peer
110        from ..models.room_config import RoomConfig
111
112        d = src_dict.copy()
113        components = []
114        _components = d.pop("components")
115        for components_item_data in _components:
116
117            def _parse_components_item(
118                data: object,
119            ) -> Union[
120                "ComponentFile",
121                "ComponentHLS",
122                "ComponentRTSP",
123                "ComponentRecording",
124                "ComponentSIP",
125            ]:
126                try:
127                    if not isinstance(data, dict):
128                        raise TypeError()
129                    componentsschemas_component_type_0 = ComponentHLS.from_dict(data)
130
131                    return componentsschemas_component_type_0
132                except:  # noqa: E722
133                    pass
134                try:
135                    if not isinstance(data, dict):
136                        raise TypeError()
137                    componentsschemas_component_type_1 = ComponentRTSP.from_dict(data)
138
139                    return componentsschemas_component_type_1
140                except:  # noqa: E722
141                    pass
142                try:
143                    if not isinstance(data, dict):
144                        raise TypeError()
145                    componentsschemas_component_type_2 = ComponentFile.from_dict(data)
146
147                    return componentsschemas_component_type_2
148                except:  # noqa: E722
149                    pass
150                try:
151                    if not isinstance(data, dict):
152                        raise TypeError()
153                    componentsschemas_component_type_3 = ComponentSIP.from_dict(data)
154
155                    return componentsschemas_component_type_3
156                except:  # noqa: E722
157                    pass
158                if not isinstance(data, dict):
159                    raise TypeError()
160                componentsschemas_component_type_4 = ComponentRecording.from_dict(data)
161
162                return componentsschemas_component_type_4
163
164            components_item = _parse_components_item(components_item_data)
165
166            components.append(components_item)
167
168        config = RoomConfig.from_dict(d.pop("config"))
169
170        id = d.pop("id")
171
172        peers = []
173        _peers = d.pop("peers")
174        for peers_item_data in _peers:
175            peers_item = Peer.from_dict(peers_item_data)
176
177            peers.append(peers_item)
178
179        room = cls(
180            components=components,
181            config=config,
182            id=id,
183            peers=peers,
184        )
185
186        room.additional_properties = d
187        return room
188
189    @property
190    def additional_keys(self) -> List[str]:
191        """@private"""
192        return list(self.additional_properties.keys())
193
194    def __getitem__(self, key: str) -> Any:
195        return self.additional_properties[key]
196
197    def __setitem__(self, key: str, value: Any) -> None:
198        self.additional_properties[key] = value
199
200    def __delitem__(self, key: str) -> None:
201        del self.additional_properties[key]
202
203    def __contains__(self, key: str) -> bool:
204        return key in self.additional_properties

Description of the room state

Room( components: List[Union[ComponentFile, ComponentHLS, ComponentRTSP, ComponentRecording, ComponentSIP]], config: RoomConfig, id: str, peers: List[Peer])
2def __init__(self, components, config, id, peers):
3    self.components = components
4    self.config = config
5    self.id = id
6    self.peers = peers
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class Room.

List of all components

config: RoomConfig

Room configuration

id: str

Room ID

peers: List[Peer]

List of all peers

class RoomConfig:
 13@_attrs_define
 14class RoomConfig:
 15    """Room configuration"""
 16
 17    max_peers: Union[Unset, None, int] = UNSET
 18    """Maximum amount of peers allowed into the room"""
 19    peer_disconnected_timeout: Union[Unset, None, int] = UNSET
 20    """Duration (in seconds) after which the peer will be removed if it is disconnected. If not provided, this feature is disabled."""
 21    peerless_purge_timeout: Union[Unset, None, int] = UNSET
 22    """Duration (in seconds) after which the room will be removed if no peers are connected. If not provided, this feature is disabled."""
 23    room_id: Union[Unset, None, str] = UNSET
 24    """Custom id used for identifying room within Jellyfish. Must be unique across all rooms. If not provided, random UUID is generated."""
 25    video_codec: Union[Unset, None, RoomConfigVideoCodec] = UNSET
 26    """Enforces video codec for each peer in the room"""
 27    webhook_url: Union[Unset, None, str] = UNSET
 28    """URL where Jellyfish notifications will be sent"""
 29    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 30    """@private"""
 31
 32    def to_dict(self) -> Dict[str, Any]:
 33        """@private"""
 34        max_peers = self.max_peers
 35        peer_disconnected_timeout = self.peer_disconnected_timeout
 36        peerless_purge_timeout = self.peerless_purge_timeout
 37        room_id = self.room_id
 38        video_codec: Union[Unset, None, str] = UNSET
 39        if not isinstance(self.video_codec, Unset):
 40            video_codec = self.video_codec.value if self.video_codec else None
 41
 42        webhook_url = self.webhook_url
 43
 44        field_dict: Dict[str, Any] = {}
 45        field_dict.update(self.additional_properties)
 46        field_dict.update({})
 47        if max_peers is not UNSET:
 48            field_dict["maxPeers"] = max_peers
 49        if peer_disconnected_timeout is not UNSET:
 50            field_dict["peerDisconnectedTimeout"] = peer_disconnected_timeout
 51        if peerless_purge_timeout is not UNSET:
 52            field_dict["peerlessPurgeTimeout"] = peerless_purge_timeout
 53        if room_id is not UNSET:
 54            field_dict["roomId"] = room_id
 55        if video_codec is not UNSET:
 56            field_dict["videoCodec"] = video_codec
 57        if webhook_url is not UNSET:
 58            field_dict["webhookUrl"] = webhook_url
 59
 60        return field_dict
 61
 62    @classmethod
 63    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 64        """@private"""
 65        d = src_dict.copy()
 66        max_peers = d.pop("maxPeers", UNSET)
 67
 68        peer_disconnected_timeout = d.pop("peerDisconnectedTimeout", UNSET)
 69
 70        peerless_purge_timeout = d.pop("peerlessPurgeTimeout", UNSET)
 71
 72        room_id = d.pop("roomId", UNSET)
 73
 74        _video_codec = d.pop("videoCodec", UNSET)
 75        video_codec: Union[Unset, None, RoomConfigVideoCodec]
 76        if _video_codec is None:
 77            video_codec = None
 78        elif isinstance(_video_codec, Unset):
 79            video_codec = UNSET
 80        else:
 81            video_codec = RoomConfigVideoCodec(_video_codec)
 82
 83        webhook_url = d.pop("webhookUrl", UNSET)
 84
 85        room_config = cls(
 86            max_peers=max_peers,
 87            peer_disconnected_timeout=peer_disconnected_timeout,
 88            peerless_purge_timeout=peerless_purge_timeout,
 89            room_id=room_id,
 90            video_codec=video_codec,
 91            webhook_url=webhook_url,
 92        )
 93
 94        room_config.additional_properties = d
 95        return room_config
 96
 97    @property
 98    def additional_keys(self) -> List[str]:
 99        """@private"""
100        return list(self.additional_properties.keys())
101
102    def __getitem__(self, key: str) -> Any:
103        return self.additional_properties[key]
104
105    def __setitem__(self, key: str, value: Any) -> None:
106        self.additional_properties[key] = value
107
108    def __delitem__(self, key: str) -> None:
109        del self.additional_properties[key]
110
111    def __contains__(self, key: str) -> bool:
112        return key in self.additional_properties

Room configuration

RoomConfig( max_peers: Union[jellyfish._openapi_client.types.Unset, NoneType, int] = <jellyfish._openapi_client.types.Unset object>, peer_disconnected_timeout: Union[jellyfish._openapi_client.types.Unset, NoneType, int] = <jellyfish._openapi_client.types.Unset object>, peerless_purge_timeout: Union[jellyfish._openapi_client.types.Unset, NoneType, int] = <jellyfish._openapi_client.types.Unset object>, room_id: Union[jellyfish._openapi_client.types.Unset, NoneType, str] = <jellyfish._openapi_client.types.Unset object>, video_codec: Union[jellyfish._openapi_client.types.Unset, NoneType, RoomConfigVideoCodec] = <jellyfish._openapi_client.types.Unset object>, webhook_url: Union[jellyfish._openapi_client.types.Unset, NoneType, str] = <jellyfish._openapi_client.types.Unset object>)
2def __init__(self, max_peers=attr_dict['max_peers'].default, peer_disconnected_timeout=attr_dict['peer_disconnected_timeout'].default, peerless_purge_timeout=attr_dict['peerless_purge_timeout'].default, room_id=attr_dict['room_id'].default, video_codec=attr_dict['video_codec'].default, webhook_url=attr_dict['webhook_url'].default):
3    self.max_peers = max_peers
4    self.peer_disconnected_timeout = peer_disconnected_timeout
5    self.peerless_purge_timeout = peerless_purge_timeout
6    self.room_id = room_id
7    self.video_codec = video_codec
8    self.webhook_url = webhook_url
9    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class RoomConfig.

max_peers: Union[jellyfish._openapi_client.types.Unset, NoneType, int]

Maximum amount of peers allowed into the room

peer_disconnected_timeout: Union[jellyfish._openapi_client.types.Unset, NoneType, int]

Duration (in seconds) after which the peer will be removed if it is disconnected. If not provided, this feature is disabled.

peerless_purge_timeout: Union[jellyfish._openapi_client.types.Unset, NoneType, int]

Duration (in seconds) after which the room will be removed if no peers are connected. If not provided, this feature is disabled.

room_id: Union[jellyfish._openapi_client.types.Unset, NoneType, str]

Custom id used for identifying room within Jellyfish. Must be unique across all rooms. If not provided, random UUID is generated.

video_codec: Union[jellyfish._openapi_client.types.Unset, NoneType, RoomConfigVideoCodec]

Enforces video codec for each peer in the room

webhook_url: Union[jellyfish._openapi_client.types.Unset, NoneType, str]

URL where Jellyfish notifications will be sent

class RoomConfigVideoCodec(builtins.str, enum.Enum):
 5class RoomConfigVideoCodec(str, Enum):
 6    """Enforces video codec for each peer in the room"""
 7
 8    H264 = "h264"
 9    VP8 = "vp8"
10
11    def __str__(self) -> str:
12        return str(self.value)

Enforces video codec for each peer in the room

H264 = <RoomConfigVideoCodec.H264: 'h264'>
VP8 = <RoomConfigVideoCodec.VP8: 'vp8'>
Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class Peer:
 16@_attrs_define
 17class Peer:
 18    """Describes peer status"""
 19
 20    id: str
 21    """Assigned peer id"""
 22    metadata: Any
 23    """Custom metadata set by the peer"""
 24    status: PeerStatus
 25    """Informs about the peer status"""
 26    tracks: List["Track"]
 27    """List of all peer's tracks"""
 28    type: str
 29    """Peer type"""
 30    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 31    """@private"""
 32
 33    def to_dict(self) -> Dict[str, Any]:
 34        """@private"""
 35        id = self.id
 36        metadata = self.metadata
 37        status = self.status.value
 38
 39        tracks = []
 40        for tracks_item_data in self.tracks:
 41            tracks_item = tracks_item_data.to_dict()
 42
 43            tracks.append(tracks_item)
 44
 45        type = self.type
 46
 47        field_dict: Dict[str, Any] = {}
 48        field_dict.update(self.additional_properties)
 49        field_dict.update(
 50            {
 51                "id": id,
 52                "metadata": metadata,
 53                "status": status,
 54                "tracks": tracks,
 55                "type": type,
 56            }
 57        )
 58
 59        return field_dict
 60
 61    @classmethod
 62    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 63        """@private"""
 64        from ..models.track import Track
 65
 66        d = src_dict.copy()
 67        id = d.pop("id")
 68
 69        metadata = d.pop("metadata")
 70
 71        status = PeerStatus(d.pop("status"))
 72
 73        tracks = []
 74        _tracks = d.pop("tracks")
 75        for tracks_item_data in _tracks:
 76            tracks_item = Track.from_dict(tracks_item_data)
 77
 78            tracks.append(tracks_item)
 79
 80        type = d.pop("type")
 81
 82        peer = cls(
 83            id=id,
 84            metadata=metadata,
 85            status=status,
 86            tracks=tracks,
 87            type=type,
 88        )
 89
 90        peer.additional_properties = d
 91        return peer
 92
 93    @property
 94    def additional_keys(self) -> List[str]:
 95        """@private"""
 96        return list(self.additional_properties.keys())
 97
 98    def __getitem__(self, key: str) -> Any:
 99        return self.additional_properties[key]
100
101    def __setitem__(self, key: str, value: Any) -> None:
102        self.additional_properties[key] = value
103
104    def __delitem__(self, key: str) -> None:
105        del self.additional_properties[key]
106
107    def __contains__(self, key: str) -> bool:
108        return key in self.additional_properties

Describes peer status

Peer( id: str, metadata: Any, status: PeerStatus, tracks: List[jellyfish._openapi_client.models.track.Track], type: str)
2def __init__(self, id, metadata, status, tracks, type):
3    self.id = id
4    self.metadata = metadata
5    self.status = status
6    self.tracks = tracks
7    self.type = type
8    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class Peer.

id: str

Assigned peer id

metadata: Any

Custom metadata set by the peer

status: PeerStatus

Informs about the peer status

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all peer's tracks

type: str

Peer type

class PeerOptionsWebRTC:
12@_attrs_define
13class PeerOptionsWebRTC:
14    """Options specific to the WebRTC peer"""
15
16    enable_simulcast: Union[Unset, bool] = True
17    """Enables the peer to use simulcast"""
18    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
19    """@private"""
20
21    def to_dict(self) -> Dict[str, Any]:
22        """@private"""
23        enable_simulcast = self.enable_simulcast
24
25        field_dict: Dict[str, Any] = {}
26        field_dict.update(self.additional_properties)
27        field_dict.update({})
28        if enable_simulcast is not UNSET:
29            field_dict["enableSimulcast"] = enable_simulcast
30
31        return field_dict
32
33    @classmethod
34    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
35        """@private"""
36        d = src_dict.copy()
37        enable_simulcast = d.pop("enableSimulcast", UNSET)
38
39        peer_options_web_rtc = cls(
40            enable_simulcast=enable_simulcast,
41        )
42
43        peer_options_web_rtc.additional_properties = d
44        return peer_options_web_rtc
45
46    @property
47    def additional_keys(self) -> List[str]:
48        """@private"""
49        return list(self.additional_properties.keys())
50
51    def __getitem__(self, key: str) -> Any:
52        return self.additional_properties[key]
53
54    def __setitem__(self, key: str, value: Any) -> None:
55        self.additional_properties[key] = value
56
57    def __delitem__(self, key: str) -> None:
58        del self.additional_properties[key]
59
60    def __contains__(self, key: str) -> bool:
61        return key in self.additional_properties

Options specific to the WebRTC peer

PeerOptionsWebRTC( enable_simulcast: Union[jellyfish._openapi_client.types.Unset, bool] = True)
2def __init__(self, enable_simulcast=attr_dict['enable_simulcast'].default):
3    self.enable_simulcast = enable_simulcast
4    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class PeerOptionsWebRTC.

enable_simulcast: Union[jellyfish._openapi_client.types.Unset, bool]

Enables the peer to use simulcast

class PeerStatus(builtins.str, enum.Enum):
 5class PeerStatus(str, Enum):
 6    """Informs about the peer status"""
 7
 8    CONNECTED = "connected"
 9    DISCONNECTED = "disconnected"
10
11    def __str__(self) -> str:
12        return str(self.value)

Informs about the peer status

CONNECTED = <PeerStatus.CONNECTED: 'connected'>
DISCONNECTED = <PeerStatus.DISCONNECTED: 'disconnected'>
Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class ComponentHLS:
 15@_attrs_define
 16class ComponentHLS:
 17    """Describes the HLS component"""
 18
 19    id: str
 20    """Assigned component ID"""
 21    properties: "ComponentPropertiesHLS"
 22    """Properties specific to the HLS component"""
 23    tracks: List["Track"]
 24    """List of all component's tracks"""
 25    type: str
 26    """Component type"""
 27    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 28    """@private"""
 29
 30    def to_dict(self) -> Dict[str, Any]:
 31        """@private"""
 32        id = self.id
 33        properties = self.properties.to_dict()
 34
 35        tracks = []
 36        for tracks_item_data in self.tracks:
 37            tracks_item = tracks_item_data.to_dict()
 38
 39            tracks.append(tracks_item)
 40
 41        type = self.type
 42
 43        field_dict: Dict[str, Any] = {}
 44        field_dict.update(self.additional_properties)
 45        field_dict.update(
 46            {
 47                "id": id,
 48                "properties": properties,
 49                "tracks": tracks,
 50                "type": type,
 51            }
 52        )
 53
 54        return field_dict
 55
 56    @classmethod
 57    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 58        """@private"""
 59        from ..models.component_properties_hls import ComponentPropertiesHLS
 60        from ..models.track import Track
 61
 62        d = src_dict.copy()
 63        id = d.pop("id")
 64
 65        properties = ComponentPropertiesHLS.from_dict(d.pop("properties"))
 66
 67        tracks = []
 68        _tracks = d.pop("tracks")
 69        for tracks_item_data in _tracks:
 70            tracks_item = Track.from_dict(tracks_item_data)
 71
 72            tracks.append(tracks_item)
 73
 74        type = d.pop("type")
 75
 76        component_hls = cls(
 77            id=id,
 78            properties=properties,
 79            tracks=tracks,
 80            type=type,
 81        )
 82
 83        component_hls.additional_properties = d
 84        return component_hls
 85
 86    @property
 87    def additional_keys(self) -> List[str]:
 88        """@private"""
 89        return list(self.additional_properties.keys())
 90
 91    def __getitem__(self, key: str) -> Any:
 92        return self.additional_properties[key]
 93
 94    def __setitem__(self, key: str, value: Any) -> None:
 95        self.additional_properties[key] = value
 96
 97    def __delitem__(self, key: str) -> None:
 98        del self.additional_properties[key]
 99
100    def __contains__(self, key: str) -> bool:
101        return key in self.additional_properties

Describes the HLS component

ComponentHLS( id: str, properties: ComponentPropertiesHLS, tracks: List[jellyfish._openapi_client.models.track.Track], type: str)
2def __init__(self, id, properties, tracks, type):
3    self.id = id
4    self.properties = properties
5    self.tracks = tracks
6    self.type = type
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentHLS.

id: str

Assigned component ID

Properties specific to the HLS component

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all component's tracks

type: str

Component type

class ComponentOptionsHLS:
 19@_attrs_define
 20class ComponentOptionsHLS:
 21    """Options specific to the HLS component"""
 22
 23    low_latency: Union[Unset, bool] = False
 24    """Whether the component should use LL-HLS"""
 25    persistent: Union[Unset, bool] = False
 26    """Whether the video is stored after end of stream"""
 27    s3: Union[Unset, None, "S3Credentials"] = UNSET
 28    """An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided"""
 29    subscribe_mode: Union[
 30        Unset, ComponentOptionsHLSSubscribeMode
 31    ] = ComponentOptionsHLSSubscribeMode.AUTO
 32    """Whether the HLS component should subscribe to tracks automatically or manually."""
 33    target_window_duration: Union[Unset, None, int] = UNSET
 34    """Duration of stream available for viewer"""
 35    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 36    """@private"""
 37
 38    def to_dict(self) -> Dict[str, Any]:
 39        """@private"""
 40        low_latency = self.low_latency
 41        persistent = self.persistent
 42        s3: Union[Unset, None, Dict[str, Any]] = UNSET
 43        if not isinstance(self.s3, Unset):
 44            s3 = self.s3.to_dict() if self.s3 else None
 45
 46        subscribe_mode: Union[Unset, str] = UNSET
 47        if not isinstance(self.subscribe_mode, Unset):
 48            subscribe_mode = self.subscribe_mode.value
 49
 50        target_window_duration = self.target_window_duration
 51
 52        field_dict: Dict[str, Any] = {}
 53        field_dict.update(self.additional_properties)
 54        field_dict.update({})
 55        if low_latency is not UNSET:
 56            field_dict["lowLatency"] = low_latency
 57        if persistent is not UNSET:
 58            field_dict["persistent"] = persistent
 59        if s3 is not UNSET:
 60            field_dict["s3"] = s3
 61        if subscribe_mode is not UNSET:
 62            field_dict["subscribeMode"] = subscribe_mode
 63        if target_window_duration is not UNSET:
 64            field_dict["targetWindowDuration"] = target_window_duration
 65
 66        return field_dict
 67
 68    @classmethod
 69    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 70        """@private"""
 71        from ..models.s3_credentials import S3Credentials
 72
 73        d = src_dict.copy()
 74        low_latency = d.pop("lowLatency", UNSET)
 75
 76        persistent = d.pop("persistent", UNSET)
 77
 78        _s3 = d.pop("s3", UNSET)
 79        s3: Union[Unset, None, S3Credentials]
 80        if _s3 is None:
 81            s3 = None
 82        elif isinstance(_s3, Unset):
 83            s3 = UNSET
 84        else:
 85            s3 = S3Credentials.from_dict(_s3)
 86
 87        _subscribe_mode = d.pop("subscribeMode", UNSET)
 88        subscribe_mode: Union[Unset, ComponentOptionsHLSSubscribeMode]
 89        if isinstance(_subscribe_mode, Unset):
 90            subscribe_mode = UNSET
 91        else:
 92            subscribe_mode = ComponentOptionsHLSSubscribeMode(_subscribe_mode)
 93
 94        target_window_duration = d.pop("targetWindowDuration", UNSET)
 95
 96        component_options_hls = cls(
 97            low_latency=low_latency,
 98            persistent=persistent,
 99            s3=s3,
100            subscribe_mode=subscribe_mode,
101            target_window_duration=target_window_duration,
102        )
103
104        component_options_hls.additional_properties = d
105        return component_options_hls
106
107    @property
108    def additional_keys(self) -> List[str]:
109        """@private"""
110        return list(self.additional_properties.keys())
111
112    def __getitem__(self, key: str) -> Any:
113        return self.additional_properties[key]
114
115    def __setitem__(self, key: str, value: Any) -> None:
116        self.additional_properties[key] = value
117
118    def __delitem__(self, key: str) -> None:
119        del self.additional_properties[key]
120
121    def __contains__(self, key: str) -> bool:
122        return key in self.additional_properties

Options specific to the HLS component

ComponentOptionsHLS( low_latency: Union[jellyfish._openapi_client.types.Unset, bool] = False, persistent: Union[jellyfish._openapi_client.types.Unset, bool] = False, s3: Union[jellyfish._openapi_client.types.Unset, NoneType, S3Credentials] = <jellyfish._openapi_client.types.Unset object>, subscribe_mode: Union[jellyfish._openapi_client.types.Unset, ComponentOptionsHLSSubscribeMode] = <ComponentOptionsHLSSubscribeMode.AUTO: 'auto'>, target_window_duration: Union[jellyfish._openapi_client.types.Unset, NoneType, int] = <jellyfish._openapi_client.types.Unset object>)
2def __init__(self, low_latency=attr_dict['low_latency'].default, persistent=attr_dict['persistent'].default, s3=attr_dict['s3'].default, subscribe_mode=attr_dict['subscribe_mode'].default, target_window_duration=attr_dict['target_window_duration'].default):
3    self.low_latency = low_latency
4    self.persistent = persistent
5    self.s3 = s3
6    self.subscribe_mode = subscribe_mode
7    self.target_window_duration = target_window_duration
8    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentOptionsHLS.

low_latency: Union[jellyfish._openapi_client.types.Unset, bool]

Whether the component should use LL-HLS

persistent: Union[jellyfish._openapi_client.types.Unset, bool]

Whether the video is stored after end of stream

s3: Union[jellyfish._openapi_client.types.Unset, NoneType, S3Credentials]

An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided

subscribe_mode: Union[jellyfish._openapi_client.types.Unset, ComponentOptionsHLSSubscribeMode]

Whether the HLS component should subscribe to tracks automatically or manually.

target_window_duration: Union[jellyfish._openapi_client.types.Unset, NoneType, int]

Duration of stream available for viewer

class ComponentOptionsHLSSubscribeMode(builtins.str, enum.Enum):
 5class ComponentOptionsHLSSubscribeMode(str, Enum):
 6    """Whether the HLS component should subscribe to tracks automatically or manually."""
 7
 8    AUTO = "auto"
 9    MANUAL = "manual"
10
11    def __str__(self) -> str:
12        return str(self.value)

Whether the HLS component should subscribe to tracks automatically or manually.

Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class ComponentPropertiesHLS:
14@_attrs_define
15class ComponentPropertiesHLS:
16    """Properties specific to the HLS component"""
17
18    low_latency: bool
19    """Whether the component uses LL-HLS"""
20    persistent: bool
21    """Whether the video is stored after end of stream"""
22    playable: bool
23    """Whether the generated HLS playlist is playable"""
24    subscribe_mode: ComponentPropertiesHLSSubscribeMode
25    """Whether the HLS component should subscribe to tracks automatically or manually"""
26    target_window_duration: Optional[int]
27    """Duration of stream available for viewer"""
28    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
29    """@private"""
30
31    def to_dict(self) -> Dict[str, Any]:
32        """@private"""
33        low_latency = self.low_latency
34        persistent = self.persistent
35        playable = self.playable
36        subscribe_mode = self.subscribe_mode.value
37
38        target_window_duration = self.target_window_duration
39
40        field_dict: Dict[str, Any] = {}
41        field_dict.update(self.additional_properties)
42        field_dict.update(
43            {
44                "lowLatency": low_latency,
45                "persistent": persistent,
46                "playable": playable,
47                "subscribeMode": subscribe_mode,
48                "targetWindowDuration": target_window_duration,
49            }
50        )
51
52        return field_dict
53
54    @classmethod
55    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
56        """@private"""
57        d = src_dict.copy()
58        low_latency = d.pop("lowLatency")
59
60        persistent = d.pop("persistent")
61
62        playable = d.pop("playable")
63
64        subscribe_mode = ComponentPropertiesHLSSubscribeMode(d.pop("subscribeMode"))
65
66        target_window_duration = d.pop("targetWindowDuration")
67
68        component_properties_hls = cls(
69            low_latency=low_latency,
70            persistent=persistent,
71            playable=playable,
72            subscribe_mode=subscribe_mode,
73            target_window_duration=target_window_duration,
74        )
75
76        component_properties_hls.additional_properties = d
77        return component_properties_hls
78
79    @property
80    def additional_keys(self) -> List[str]:
81        """@private"""
82        return list(self.additional_properties.keys())
83
84    def __getitem__(self, key: str) -> Any:
85        return self.additional_properties[key]
86
87    def __setitem__(self, key: str, value: Any) -> None:
88        self.additional_properties[key] = value
89
90    def __delitem__(self, key: str) -> None:
91        del self.additional_properties[key]
92
93    def __contains__(self, key: str) -> bool:
94        return key in self.additional_properties

Properties specific to the HLS component

ComponentPropertiesHLS( low_latency: bool, persistent: bool, playable: bool, subscribe_mode: ComponentPropertiesHLSSubscribeMode, target_window_duration: Optional[int])
2def __init__(self, low_latency, persistent, playable, subscribe_mode, target_window_duration):
3    self.low_latency = low_latency
4    self.persistent = persistent
5    self.playable = playable
6    self.subscribe_mode = subscribe_mode
7    self.target_window_duration = target_window_duration
8    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesHLS.

low_latency: bool

Whether the component uses LL-HLS

persistent: bool

Whether the video is stored after end of stream

playable: bool

Whether the generated HLS playlist is playable

Whether the HLS component should subscribe to tracks automatically or manually

target_window_duration: Optional[int]

Duration of stream available for viewer

class ComponentPropertiesHLSSubscribeMode(builtins.str, enum.Enum):
 5class ComponentPropertiesHLSSubscribeMode(str, Enum):
 6    """Whether the HLS component should subscribe to tracks automatically or manually"""
 7
 8    AUTO = "auto"
 9    MANUAL = "manual"
10
11    def __str__(self) -> str:
12        return str(self.value)

Whether the HLS component should subscribe to tracks automatically or manually

Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class ComponentSIP:
 15@_attrs_define
 16class ComponentSIP:
 17    """Describes the SIP component"""
 18
 19    id: str
 20    """Assigned component ID"""
 21    properties: "ComponentPropertiesSIP"
 22    """Properties specific to the SIP component"""
 23    tracks: List["Track"]
 24    """List of all component's tracks"""
 25    type: str
 26    """Component type"""
 27    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 28    """@private"""
 29
 30    def to_dict(self) -> Dict[str, Any]:
 31        """@private"""
 32        id = self.id
 33        properties = self.properties.to_dict()
 34
 35        tracks = []
 36        for tracks_item_data in self.tracks:
 37            tracks_item = tracks_item_data.to_dict()
 38
 39            tracks.append(tracks_item)
 40
 41        type = self.type
 42
 43        field_dict: Dict[str, Any] = {}
 44        field_dict.update(self.additional_properties)
 45        field_dict.update(
 46            {
 47                "id": id,
 48                "properties": properties,
 49                "tracks": tracks,
 50                "type": type,
 51            }
 52        )
 53
 54        return field_dict
 55
 56    @classmethod
 57    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 58        """@private"""
 59        from ..models.component_properties_sip import ComponentPropertiesSIP
 60        from ..models.track import Track
 61
 62        d = src_dict.copy()
 63        id = d.pop("id")
 64
 65        properties = ComponentPropertiesSIP.from_dict(d.pop("properties"))
 66
 67        tracks = []
 68        _tracks = d.pop("tracks")
 69        for tracks_item_data in _tracks:
 70            tracks_item = Track.from_dict(tracks_item_data)
 71
 72            tracks.append(tracks_item)
 73
 74        type = d.pop("type")
 75
 76        component_sip = cls(
 77            id=id,
 78            properties=properties,
 79            tracks=tracks,
 80            type=type,
 81        )
 82
 83        component_sip.additional_properties = d
 84        return component_sip
 85
 86    @property
 87    def additional_keys(self) -> List[str]:
 88        """@private"""
 89        return list(self.additional_properties.keys())
 90
 91    def __getitem__(self, key: str) -> Any:
 92        return self.additional_properties[key]
 93
 94    def __setitem__(self, key: str, value: Any) -> None:
 95        self.additional_properties[key] = value
 96
 97    def __delitem__(self, key: str) -> None:
 98        del self.additional_properties[key]
 99
100    def __contains__(self, key: str) -> bool:
101        return key in self.additional_properties

Describes the SIP component

ComponentSIP( id: str, properties: ComponentPropertiesSIP, tracks: List[jellyfish._openapi_client.models.track.Track], type: str)
2def __init__(self, id, properties, tracks, type):
3    self.id = id
4    self.properties = properties
5    self.tracks = tracks
6    self.type = type
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentSIP.

id: str

Assigned component ID

Properties specific to the SIP component

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all component's tracks

type: str

Component type

class ComponentOptionsSIP:
16@_attrs_define
17class ComponentOptionsSIP:
18    """Options specific to the SIP component"""
19
20    registrar_credentials: "ComponentOptionsSIPSIPCredentials"
21    """Credentials used to authorize in SIP Provider service"""
22    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
23    """@private"""
24
25    def to_dict(self) -> Dict[str, Any]:
26        """@private"""
27        registrar_credentials = self.registrar_credentials.to_dict()
28
29        field_dict: Dict[str, Any] = {}
30        field_dict.update(self.additional_properties)
31        field_dict.update(
32            {
33                "registrarCredentials": registrar_credentials,
34            }
35        )
36
37        return field_dict
38
39    @classmethod
40    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
41        """@private"""
42        from ..models.component_options_sipsip_credentials import (
43            ComponentOptionsSIPSIPCredentials,
44        )
45
46        d = src_dict.copy()
47        registrar_credentials = ComponentOptionsSIPSIPCredentials.from_dict(
48            d.pop("registrarCredentials")
49        )
50
51        component_options_sip = cls(
52            registrar_credentials=registrar_credentials,
53        )
54
55        component_options_sip.additional_properties = d
56        return component_options_sip
57
58    @property
59    def additional_keys(self) -> List[str]:
60        """@private"""
61        return list(self.additional_properties.keys())
62
63    def __getitem__(self, key: str) -> Any:
64        return self.additional_properties[key]
65
66    def __setitem__(self, key: str, value: Any) -> None:
67        self.additional_properties[key] = value
68
69    def __delitem__(self, key: str) -> None:
70        del self.additional_properties[key]
71
72    def __contains__(self, key: str) -> bool:
73        return key in self.additional_properties

Options specific to the SIP component

ComponentOptionsSIP( registrar_credentials: jellyfish._openapi_client.models.component_options_sipsip_credentials.ComponentOptionsSIPSIPCredentials)
2def __init__(self, registrar_credentials):
3    self.registrar_credentials = registrar_credentials
4    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentOptionsSIP.

registrar_credentials: jellyfish._openapi_client.models.component_options_sipsip_credentials.ComponentOptionsSIPSIPCredentials

Credentials used to authorize in SIP Provider service

class ComponentPropertiesSIP:
16@_attrs_define
17class ComponentPropertiesSIP:
18    """Properties specific to the SIP component"""
19
20    registrar_credentials: "ComponentPropertiesSIPSIPCredentials"
21    """Credentials used to authorize in SIP Provider service"""
22    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
23    """@private"""
24
25    def to_dict(self) -> Dict[str, Any]:
26        """@private"""
27        registrar_credentials = self.registrar_credentials.to_dict()
28
29        field_dict: Dict[str, Any] = {}
30        field_dict.update(self.additional_properties)
31        field_dict.update(
32            {
33                "registrarCredentials": registrar_credentials,
34            }
35        )
36
37        return field_dict
38
39    @classmethod
40    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
41        """@private"""
42        from ..models.component_properties_sipsip_credentials import (
43            ComponentPropertiesSIPSIPCredentials,
44        )
45
46        d = src_dict.copy()
47        registrar_credentials = ComponentPropertiesSIPSIPCredentials.from_dict(
48            d.pop("registrarCredentials")
49        )
50
51        component_properties_sip = cls(
52            registrar_credentials=registrar_credentials,
53        )
54
55        component_properties_sip.additional_properties = d
56        return component_properties_sip
57
58    @property
59    def additional_keys(self) -> List[str]:
60        """@private"""
61        return list(self.additional_properties.keys())
62
63    def __getitem__(self, key: str) -> Any:
64        return self.additional_properties[key]
65
66    def __setitem__(self, key: str, value: Any) -> None:
67        self.additional_properties[key] = value
68
69    def __delitem__(self, key: str) -> None:
70        del self.additional_properties[key]
71
72    def __contains__(self, key: str) -> bool:
73        return key in self.additional_properties

Properties specific to the SIP component

ComponentPropertiesSIP( registrar_credentials: ComponentPropertiesSIPSIPCredentials)
2def __init__(self, registrar_credentials):
3    self.registrar_credentials = registrar_credentials
4    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesSIP.

registrar_credentials: ComponentPropertiesSIPSIPCredentials

Credentials used to authorize in SIP Provider service

class ComponentPropertiesSIPSIPCredentials:
10@_attrs_define
11class ComponentPropertiesSIPSIPCredentials:
12    """Credentials used to authorize in SIP Provider service"""
13
14    address: str
15    """SIP provider address. Can be in the form of FQDN (my-sip-registrar.net) or IPv4 (1.2.3.4). Port can be specified e.g: 5.6.7.8:9999. If not given, the default SIP port `5060` will be assumed"""
16    password: str
17    """Password in SIP service provider"""
18    username: str
19    """Username in SIP service provider"""
20    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
21    """@private"""
22
23    def to_dict(self) -> Dict[str, Any]:
24        """@private"""
25        address = self.address
26        password = self.password
27        username = self.username
28
29        field_dict: Dict[str, Any] = {}
30        field_dict.update(self.additional_properties)
31        field_dict.update(
32            {
33                "address": address,
34                "password": password,
35                "username": username,
36            }
37        )
38
39        return field_dict
40
41    @classmethod
42    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
43        """@private"""
44        d = src_dict.copy()
45        address = d.pop("address")
46
47        password = d.pop("password")
48
49        username = d.pop("username")
50
51        component_properties_sipsip_credentials = cls(
52            address=address,
53            password=password,
54            username=username,
55        )
56
57        component_properties_sipsip_credentials.additional_properties = d
58        return component_properties_sipsip_credentials
59
60    @property
61    def additional_keys(self) -> List[str]:
62        """@private"""
63        return list(self.additional_properties.keys())
64
65    def __getitem__(self, key: str) -> Any:
66        return self.additional_properties[key]
67
68    def __setitem__(self, key: str, value: Any) -> None:
69        self.additional_properties[key] = value
70
71    def __delitem__(self, key: str) -> None:
72        del self.additional_properties[key]
73
74    def __contains__(self, key: str) -> bool:
75        return key in self.additional_properties

Credentials used to authorize in SIP Provider service

ComponentPropertiesSIPSIPCredentials(address: str, password: str, username: str)
2def __init__(self, address, password, username):
3    self.address = address
4    self.password = password
5    self.username = username
6    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesSIPSIPCredentials.

address: str

SIP provider address. Can be in the form of FQDN (my-sip-registrar.net) or IPv4 (1.2.3.4). Port can be specified e.g: 5.6.7.8:9999. If not given, the default SIP port 5060 will be assumed

password: str

Password in SIP service provider

username: str

Username in SIP service provider

class ComponentFile:
 17@_attrs_define
 18class ComponentFile:
 19    """Describes the File component"""
 20
 21    id: str
 22    """Assigned component ID"""
 23    tracks: List["Track"]
 24    """List of all component's tracks"""
 25    type: str
 26    """Component type"""
 27    properties: Union[Unset, "ComponentPropertiesFile"] = UNSET
 28    """Properties specific to the File component"""
 29    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 30    """@private"""
 31
 32    def to_dict(self) -> Dict[str, Any]:
 33        """@private"""
 34        id = self.id
 35        tracks = []
 36        for tracks_item_data in self.tracks:
 37            tracks_item = tracks_item_data.to_dict()
 38
 39            tracks.append(tracks_item)
 40
 41        type = self.type
 42        properties: Union[Unset, Dict[str, Any]] = UNSET
 43        if not isinstance(self.properties, Unset):
 44            properties = self.properties.to_dict()
 45
 46        field_dict: Dict[str, Any] = {}
 47        field_dict.update(self.additional_properties)
 48        field_dict.update(
 49            {
 50                "id": id,
 51                "tracks": tracks,
 52                "type": type,
 53            }
 54        )
 55        if properties is not UNSET:
 56            field_dict["properties"] = properties
 57
 58        return field_dict
 59
 60    @classmethod
 61    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 62        """@private"""
 63        from ..models.component_properties_file import ComponentPropertiesFile
 64        from ..models.track import Track
 65
 66        d = src_dict.copy()
 67        id = d.pop("id")
 68
 69        tracks = []
 70        _tracks = d.pop("tracks")
 71        for tracks_item_data in _tracks:
 72            tracks_item = Track.from_dict(tracks_item_data)
 73
 74            tracks.append(tracks_item)
 75
 76        type = d.pop("type")
 77
 78        _properties = d.pop("properties", UNSET)
 79        properties: Union[Unset, ComponentPropertiesFile]
 80        if isinstance(_properties, Unset):
 81            properties = UNSET
 82        else:
 83            properties = ComponentPropertiesFile.from_dict(_properties)
 84
 85        component_file = cls(
 86            id=id,
 87            tracks=tracks,
 88            type=type,
 89            properties=properties,
 90        )
 91
 92        component_file.additional_properties = d
 93        return component_file
 94
 95    @property
 96    def additional_keys(self) -> List[str]:
 97        """@private"""
 98        return list(self.additional_properties.keys())
 99
100    def __getitem__(self, key: str) -> Any:
101        return self.additional_properties[key]
102
103    def __setitem__(self, key: str, value: Any) -> None:
104        self.additional_properties[key] = value
105
106    def __delitem__(self, key: str) -> None:
107        del self.additional_properties[key]
108
109    def __contains__(self, key: str) -> bool:
110        return key in self.additional_properties

Describes the File component

ComponentFile( id: str, tracks: List[jellyfish._openapi_client.models.track.Track], type: str, properties: Union[jellyfish._openapi_client.types.Unset, ComponentPropertiesFile] = <jellyfish._openapi_client.types.Unset object>)
2def __init__(self, id, tracks, type, properties=attr_dict['properties'].default):
3    self.id = id
4    self.tracks = tracks
5    self.type = type
6    self.properties = properties
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentFile.

id: str

Assigned component ID

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all component's tracks

type: str

Component type

properties: Union[jellyfish._openapi_client.types.Unset, ComponentPropertiesFile]

Properties specific to the File component

class ComponentRTSP:
 15@_attrs_define
 16class ComponentRTSP:
 17    """Describes the RTSP component"""
 18
 19    id: str
 20    """Assigned component ID"""
 21    properties: "ComponentPropertiesRTSP"
 22    """Properties specific to the RTSP component"""
 23    tracks: List["Track"]
 24    """List of all component's tracks"""
 25    type: str
 26    """Component type"""
 27    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 28    """@private"""
 29
 30    def to_dict(self) -> Dict[str, Any]:
 31        """@private"""
 32        id = self.id
 33        properties = self.properties.to_dict()
 34
 35        tracks = []
 36        for tracks_item_data in self.tracks:
 37            tracks_item = tracks_item_data.to_dict()
 38
 39            tracks.append(tracks_item)
 40
 41        type = self.type
 42
 43        field_dict: Dict[str, Any] = {}
 44        field_dict.update(self.additional_properties)
 45        field_dict.update(
 46            {
 47                "id": id,
 48                "properties": properties,
 49                "tracks": tracks,
 50                "type": type,
 51            }
 52        )
 53
 54        return field_dict
 55
 56    @classmethod
 57    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 58        """@private"""
 59        from ..models.component_properties_rtsp import ComponentPropertiesRTSP
 60        from ..models.track import Track
 61
 62        d = src_dict.copy()
 63        id = d.pop("id")
 64
 65        properties = ComponentPropertiesRTSP.from_dict(d.pop("properties"))
 66
 67        tracks = []
 68        _tracks = d.pop("tracks")
 69        for tracks_item_data in _tracks:
 70            tracks_item = Track.from_dict(tracks_item_data)
 71
 72            tracks.append(tracks_item)
 73
 74        type = d.pop("type")
 75
 76        component_rtsp = cls(
 77            id=id,
 78            properties=properties,
 79            tracks=tracks,
 80            type=type,
 81        )
 82
 83        component_rtsp.additional_properties = d
 84        return component_rtsp
 85
 86    @property
 87    def additional_keys(self) -> List[str]:
 88        """@private"""
 89        return list(self.additional_properties.keys())
 90
 91    def __getitem__(self, key: str) -> Any:
 92        return self.additional_properties[key]
 93
 94    def __setitem__(self, key: str, value: Any) -> None:
 95        self.additional_properties[key] = value
 96
 97    def __delitem__(self, key: str) -> None:
 98        del self.additional_properties[key]
 99
100    def __contains__(self, key: str) -> bool:
101        return key in self.additional_properties

Describes the RTSP component

ComponentRTSP( id: str, properties: ComponentPropertiesRTSP, tracks: List[jellyfish._openapi_client.models.track.Track], type: str)
2def __init__(self, id, properties, tracks, type):
3    self.id = id
4    self.properties = properties
5    self.tracks = tracks
6    self.type = type
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentRTSP.

id: str

Assigned component ID

Properties specific to the RTSP component

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all component's tracks

type: str

Component type

class ComponentOptionsRTSP:
12@_attrs_define
13class ComponentOptionsRTSP:
14    """Options specific to the RTSP component"""
15
16    source_uri: str
17    """URI of RTSP source stream"""
18    keep_alive_interval: Union[Unset, int] = 15000
19    """Interval (in ms) in which keep-alive RTSP messages will be sent to the remote stream source"""
20    pierce_nat: Union[Unset, bool] = True
21    """Whether to attempt to create client-side NAT binding by sending an empty datagram from client to source, after the completion of RTSP setup"""
22    reconnect_delay: Union[Unset, int] = 15000
23    """Delay (in ms) between successive reconnect attempts"""
24    rtp_port: Union[Unset, int] = 20000
25    """Local port RTP stream will be received at"""
26    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
27    """@private"""
28
29    def to_dict(self) -> Dict[str, Any]:
30        """@private"""
31        source_uri = self.source_uri
32        keep_alive_interval = self.keep_alive_interval
33        pierce_nat = self.pierce_nat
34        reconnect_delay = self.reconnect_delay
35        rtp_port = self.rtp_port
36
37        field_dict: Dict[str, Any] = {}
38        field_dict.update(self.additional_properties)
39        field_dict.update(
40            {
41                "sourceUri": source_uri,
42            }
43        )
44        if keep_alive_interval is not UNSET:
45            field_dict["keepAliveInterval"] = keep_alive_interval
46        if pierce_nat is not UNSET:
47            field_dict["pierceNat"] = pierce_nat
48        if reconnect_delay is not UNSET:
49            field_dict["reconnectDelay"] = reconnect_delay
50        if rtp_port is not UNSET:
51            field_dict["rtpPort"] = rtp_port
52
53        return field_dict
54
55    @classmethod
56    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
57        """@private"""
58        d = src_dict.copy()
59        source_uri = d.pop("sourceUri")
60
61        keep_alive_interval = d.pop("keepAliveInterval", UNSET)
62
63        pierce_nat = d.pop("pierceNat", UNSET)
64
65        reconnect_delay = d.pop("reconnectDelay", UNSET)
66
67        rtp_port = d.pop("rtpPort", UNSET)
68
69        component_options_rtsp = cls(
70            source_uri=source_uri,
71            keep_alive_interval=keep_alive_interval,
72            pierce_nat=pierce_nat,
73            reconnect_delay=reconnect_delay,
74            rtp_port=rtp_port,
75        )
76
77        component_options_rtsp.additional_properties = d
78        return component_options_rtsp
79
80    @property
81    def additional_keys(self) -> List[str]:
82        """@private"""
83        return list(self.additional_properties.keys())
84
85    def __getitem__(self, key: str) -> Any:
86        return self.additional_properties[key]
87
88    def __setitem__(self, key: str, value: Any) -> None:
89        self.additional_properties[key] = value
90
91    def __delitem__(self, key: str) -> None:
92        del self.additional_properties[key]
93
94    def __contains__(self, key: str) -> bool:
95        return key in self.additional_properties

Options specific to the RTSP component

ComponentOptionsRTSP( source_uri: str, keep_alive_interval: Union[jellyfish._openapi_client.types.Unset, int] = 15000, pierce_nat: Union[jellyfish._openapi_client.types.Unset, bool] = True, reconnect_delay: Union[jellyfish._openapi_client.types.Unset, int] = 15000, rtp_port: Union[jellyfish._openapi_client.types.Unset, int] = 20000)
2def __init__(self, source_uri, keep_alive_interval=attr_dict['keep_alive_interval'].default, pierce_nat=attr_dict['pierce_nat'].default, reconnect_delay=attr_dict['reconnect_delay'].default, rtp_port=attr_dict['rtp_port'].default):
3    self.source_uri = source_uri
4    self.keep_alive_interval = keep_alive_interval
5    self.pierce_nat = pierce_nat
6    self.reconnect_delay = reconnect_delay
7    self.rtp_port = rtp_port
8    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentOptionsRTSP.

source_uri: str

URI of RTSP source stream

keep_alive_interval: Union[jellyfish._openapi_client.types.Unset, int]

Interval (in ms) in which keep-alive RTSP messages will be sent to the remote stream source

pierce_nat: Union[jellyfish._openapi_client.types.Unset, bool]

Whether to attempt to create client-side NAT binding by sending an empty datagram from client to source, after the completion of RTSP setup

reconnect_delay: Union[jellyfish._openapi_client.types.Unset, int]

Delay (in ms) between successive reconnect attempts

rtp_port: Union[jellyfish._openapi_client.types.Unset, int]

Local port RTP stream will be received at

class ComponentPropertiesRTSP:
10@_attrs_define
11class ComponentPropertiesRTSP:
12    """Properties specific to the RTSP component"""
13
14    keep_alive_interval: int
15    """Interval (in ms) in which keep-alive RTSP messages will be sent to the remote stream source"""
16    pierce_nat: bool
17    """Whether to attempt to create client-side NAT binding by sending an empty datagram from client to source, after the completion of RTSP setup"""
18    reconnect_delay: int
19    """Delay (in ms) between successive reconnect attempts"""
20    rtp_port: int
21    """Local port RTP stream will be received at"""
22    source_uri: str
23    """URI of RTSP source stream"""
24    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
25    """@private"""
26
27    def to_dict(self) -> Dict[str, Any]:
28        """@private"""
29        keep_alive_interval = self.keep_alive_interval
30        pierce_nat = self.pierce_nat
31        reconnect_delay = self.reconnect_delay
32        rtp_port = self.rtp_port
33        source_uri = self.source_uri
34
35        field_dict: Dict[str, Any] = {}
36        field_dict.update(self.additional_properties)
37        field_dict.update(
38            {
39                "keepAliveInterval": keep_alive_interval,
40                "pierceNat": pierce_nat,
41                "reconnectDelay": reconnect_delay,
42                "rtpPort": rtp_port,
43                "sourceUri": source_uri,
44            }
45        )
46
47        return field_dict
48
49    @classmethod
50    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
51        """@private"""
52        d = src_dict.copy()
53        keep_alive_interval = d.pop("keepAliveInterval")
54
55        pierce_nat = d.pop("pierceNat")
56
57        reconnect_delay = d.pop("reconnectDelay")
58
59        rtp_port = d.pop("rtpPort")
60
61        source_uri = d.pop("sourceUri")
62
63        component_properties_rtsp = cls(
64            keep_alive_interval=keep_alive_interval,
65            pierce_nat=pierce_nat,
66            reconnect_delay=reconnect_delay,
67            rtp_port=rtp_port,
68            source_uri=source_uri,
69        )
70
71        component_properties_rtsp.additional_properties = d
72        return component_properties_rtsp
73
74    @property
75    def additional_keys(self) -> List[str]:
76        """@private"""
77        return list(self.additional_properties.keys())
78
79    def __getitem__(self, key: str) -> Any:
80        return self.additional_properties[key]
81
82    def __setitem__(self, key: str, value: Any) -> None:
83        self.additional_properties[key] = value
84
85    def __delitem__(self, key: str) -> None:
86        del self.additional_properties[key]
87
88    def __contains__(self, key: str) -> bool:
89        return key in self.additional_properties

Properties specific to the RTSP component

ComponentPropertiesRTSP( keep_alive_interval: int, pierce_nat: bool, reconnect_delay: int, rtp_port: int, source_uri: str)
2def __init__(self, keep_alive_interval, pierce_nat, reconnect_delay, rtp_port, source_uri):
3    self.keep_alive_interval = keep_alive_interval
4    self.pierce_nat = pierce_nat
5    self.reconnect_delay = reconnect_delay
6    self.rtp_port = rtp_port
7    self.source_uri = source_uri
8    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesRTSP.

keep_alive_interval: int

Interval (in ms) in which keep-alive RTSP messages will be sent to the remote stream source

pierce_nat: bool

Whether to attempt to create client-side NAT binding by sending an empty datagram from client to source, after the completion of RTSP setup

reconnect_delay: int

Delay (in ms) between successive reconnect attempts

rtp_port: int

Local port RTP stream will be received at

source_uri: str

URI of RTSP source stream

class ComponentOptionsFile:
12@_attrs_define
13class ComponentOptionsFile:
14    """Options specific to the File component"""
15
16    file_path: str
17    """Path to track file. Must be either OPUS encapsulated in Ogg or raw h264"""
18    framerate: Union[Unset, None, int] = UNSET
19    """Framerate of video in a file. It is only valid for video track"""
20    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
21    """@private"""
22
23    def to_dict(self) -> Dict[str, Any]:
24        """@private"""
25        file_path = self.file_path
26        framerate = self.framerate
27
28        field_dict: Dict[str, Any] = {}
29        field_dict.update(self.additional_properties)
30        field_dict.update(
31            {
32                "filePath": file_path,
33            }
34        )
35        if framerate is not UNSET:
36            field_dict["framerate"] = framerate
37
38        return field_dict
39
40    @classmethod
41    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
42        """@private"""
43        d = src_dict.copy()
44        file_path = d.pop("filePath")
45
46        framerate = d.pop("framerate", UNSET)
47
48        component_options_file = cls(
49            file_path=file_path,
50            framerate=framerate,
51        )
52
53        component_options_file.additional_properties = d
54        return component_options_file
55
56    @property
57    def additional_keys(self) -> List[str]:
58        """@private"""
59        return list(self.additional_properties.keys())
60
61    def __getitem__(self, key: str) -> Any:
62        return self.additional_properties[key]
63
64    def __setitem__(self, key: str, value: Any) -> None:
65        self.additional_properties[key] = value
66
67    def __delitem__(self, key: str) -> None:
68        del self.additional_properties[key]
69
70    def __contains__(self, key: str) -> bool:
71        return key in self.additional_properties

Options specific to the File component

ComponentOptionsFile( file_path: str, framerate: Union[jellyfish._openapi_client.types.Unset, NoneType, int] = <jellyfish._openapi_client.types.Unset object>)
2def __init__(self, file_path, framerate=attr_dict['framerate'].default):
3    self.file_path = file_path
4    self.framerate = framerate
5    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentOptionsFile.

file_path: str

Path to track file. Must be either OPUS encapsulated in Ogg or raw h264

framerate: Union[jellyfish._openapi_client.types.Unset, NoneType, int]

Framerate of video in a file. It is only valid for video track

class ComponentPropertiesFile:
10@_attrs_define
11class ComponentPropertiesFile:
12    """Properties specific to the File component"""
13
14    file_path: str
15    """Relative path to track file. Must be either OPUS encapsulated in Ogg or raw h264"""
16    framerate: Optional[int]
17    """Framerate of video in a file. It is only valid for video track"""
18    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
19    """@private"""
20
21    def to_dict(self) -> Dict[str, Any]:
22        """@private"""
23        file_path = self.file_path
24        framerate = self.framerate
25
26        field_dict: Dict[str, Any] = {}
27        field_dict.update(self.additional_properties)
28        field_dict.update(
29            {
30                "filePath": file_path,
31                "framerate": framerate,
32            }
33        )
34
35        return field_dict
36
37    @classmethod
38    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
39        """@private"""
40        d = src_dict.copy()
41        file_path = d.pop("filePath")
42
43        framerate = d.pop("framerate")
44
45        component_properties_file = cls(
46            file_path=file_path,
47            framerate=framerate,
48        )
49
50        component_properties_file.additional_properties = d
51        return component_properties_file
52
53    @property
54    def additional_keys(self) -> List[str]:
55        """@private"""
56        return list(self.additional_properties.keys())
57
58    def __getitem__(self, key: str) -> Any:
59        return self.additional_properties[key]
60
61    def __setitem__(self, key: str, value: Any) -> None:
62        self.additional_properties[key] = value
63
64    def __delitem__(self, key: str) -> None:
65        del self.additional_properties[key]
66
67    def __contains__(self, key: str) -> bool:
68        return key in self.additional_properties

Properties specific to the File component

ComponentPropertiesFile(file_path: str, framerate: Optional[int])
2def __init__(self, file_path, framerate):
3    self.file_path = file_path
4    self.framerate = framerate
5    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesFile.

file_path: str

Relative path to track file. Must be either OPUS encapsulated in Ogg or raw h264

framerate: Optional[int]

Framerate of video in a file. It is only valid for video track

class SIPCredentials:
10@_attrs_define
11class SIPCredentials:
12    """Credentials used to authorize in SIP Provider service"""
13
14    address: str
15    """SIP provider address. Can be in the form of FQDN (my-sip-registrar.net) or IPv4 (1.2.3.4). Port can be specified e.g: 5.6.7.8:9999. If not given, the default SIP port `5060` will be assumed"""
16    password: str
17    """Password in SIP service provider"""
18    username: str
19    """Username in SIP service provider"""
20    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
21    """@private"""
22
23    def to_dict(self) -> Dict[str, Any]:
24        """@private"""
25        address = self.address
26        password = self.password
27        username = self.username
28
29        field_dict: Dict[str, Any] = {}
30        field_dict.update(self.additional_properties)
31        field_dict.update(
32            {
33                "address": address,
34                "password": password,
35                "username": username,
36            }
37        )
38
39        return field_dict
40
41    @classmethod
42    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
43        """@private"""
44        d = src_dict.copy()
45        address = d.pop("address")
46
47        password = d.pop("password")
48
49        username = d.pop("username")
50
51        sip_credentials = cls(
52            address=address,
53            password=password,
54            username=username,
55        )
56
57        sip_credentials.additional_properties = d
58        return sip_credentials
59
60    @property
61    def additional_keys(self) -> List[str]:
62        """@private"""
63        return list(self.additional_properties.keys())
64
65    def __getitem__(self, key: str) -> Any:
66        return self.additional_properties[key]
67
68    def __setitem__(self, key: str, value: Any) -> None:
69        self.additional_properties[key] = value
70
71    def __delitem__(self, key: str) -> None:
72        del self.additional_properties[key]
73
74    def __contains__(self, key: str) -> bool:
75        return key in self.additional_properties

Credentials used to authorize in SIP Provider service

SIPCredentials(address: str, password: str, username: str)
2def __init__(self, address, password, username):
3    self.address = address
4    self.password = password
5    self.username = username
6    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class SIPCredentials.

address: str

SIP provider address. Can be in the form of FQDN (my-sip-registrar.net) or IPv4 (1.2.3.4). Port can be specified e.g: 5.6.7.8:9999. If not given, the default SIP port 5060 will be assumed

password: str

Password in SIP service provider

username: str

Username in SIP service provider

class ComponentRecording:
 15@_attrs_define
 16class ComponentRecording:
 17    """Describes the Recording component"""
 18
 19    id: str
 20    """Assigned component ID"""
 21    properties: "ComponentPropertiesRecording"
 22    """Properties specific to the Recording component"""
 23    tracks: List["Track"]
 24    """List of all component's tracks"""
 25    type: str
 26    """Component type"""
 27    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 28    """@private"""
 29
 30    def to_dict(self) -> Dict[str, Any]:
 31        """@private"""
 32        id = self.id
 33        properties = self.properties.to_dict()
 34
 35        tracks = []
 36        for tracks_item_data in self.tracks:
 37            tracks_item = tracks_item_data.to_dict()
 38
 39            tracks.append(tracks_item)
 40
 41        type = self.type
 42
 43        field_dict: Dict[str, Any] = {}
 44        field_dict.update(self.additional_properties)
 45        field_dict.update(
 46            {
 47                "id": id,
 48                "properties": properties,
 49                "tracks": tracks,
 50                "type": type,
 51            }
 52        )
 53
 54        return field_dict
 55
 56    @classmethod
 57    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 58        """@private"""
 59        from ..models.component_properties_recording import ComponentPropertiesRecording
 60        from ..models.track import Track
 61
 62        d = src_dict.copy()
 63        id = d.pop("id")
 64
 65        properties = ComponentPropertiesRecording.from_dict(d.pop("properties"))
 66
 67        tracks = []
 68        _tracks = d.pop("tracks")
 69        for tracks_item_data in _tracks:
 70            tracks_item = Track.from_dict(tracks_item_data)
 71
 72            tracks.append(tracks_item)
 73
 74        type = d.pop("type")
 75
 76        component_recording = cls(
 77            id=id,
 78            properties=properties,
 79            tracks=tracks,
 80            type=type,
 81        )
 82
 83        component_recording.additional_properties = d
 84        return component_recording
 85
 86    @property
 87    def additional_keys(self) -> List[str]:
 88        """@private"""
 89        return list(self.additional_properties.keys())
 90
 91    def __getitem__(self, key: str) -> Any:
 92        return self.additional_properties[key]
 93
 94    def __setitem__(self, key: str, value: Any) -> None:
 95        self.additional_properties[key] = value
 96
 97    def __delitem__(self, key: str) -> None:
 98        del self.additional_properties[key]
 99
100    def __contains__(self, key: str) -> bool:
101        return key in self.additional_properties

Describes the Recording component

ComponentRecording( id: str, properties: ComponentPropertiesRecording, tracks: List[jellyfish._openapi_client.models.track.Track], type: str)
2def __init__(self, id, properties, tracks, type):
3    self.id = id
4    self.properties = properties
5    self.tracks = tracks
6    self.type = type
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentRecording.

id: str

Assigned component ID

Properties specific to the Recording component

tracks: List[jellyfish._openapi_client.models.track.Track]

List of all component's tracks

type: str

Component type

class ComponentOptionsRecording:
 19@_attrs_define
 20class ComponentOptionsRecording:
 21    """Options specific to the Recording component"""
 22
 23    credentials: Union[Unset, None, "S3Credentials"] = UNSET
 24    """An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided"""
 25    path_prefix: Union[Unset, None, str] = UNSET
 26    """Path prefix under which all recording are stored"""
 27    subscribe_mode: Union[
 28        Unset, ComponentOptionsRecordingSubscribeMode
 29    ] = ComponentOptionsRecordingSubscribeMode.AUTO
 30    """Whether the Recording component should subscribe to tracks automatically or manually."""
 31    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
 32    """@private"""
 33
 34    def to_dict(self) -> Dict[str, Any]:
 35        """@private"""
 36        credentials: Union[Unset, None, Dict[str, Any]] = UNSET
 37        if not isinstance(self.credentials, Unset):
 38            credentials = self.credentials.to_dict() if self.credentials else None
 39
 40        path_prefix = self.path_prefix
 41        subscribe_mode: Union[Unset, str] = UNSET
 42        if not isinstance(self.subscribe_mode, Unset):
 43            subscribe_mode = self.subscribe_mode.value
 44
 45        field_dict: Dict[str, Any] = {}
 46        field_dict.update(self.additional_properties)
 47        field_dict.update({})
 48        if credentials is not UNSET:
 49            field_dict["credentials"] = credentials
 50        if path_prefix is not UNSET:
 51            field_dict["pathPrefix"] = path_prefix
 52        if subscribe_mode is not UNSET:
 53            field_dict["subscribeMode"] = subscribe_mode
 54
 55        return field_dict
 56
 57    @classmethod
 58    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
 59        """@private"""
 60        from ..models.s3_credentials import S3Credentials
 61
 62        d = src_dict.copy()
 63        _credentials = d.pop("credentials", UNSET)
 64        credentials: Union[Unset, None, S3Credentials]
 65        if _credentials is None:
 66            credentials = None
 67        elif isinstance(_credentials, Unset):
 68            credentials = UNSET
 69        else:
 70            credentials = S3Credentials.from_dict(_credentials)
 71
 72        path_prefix = d.pop("pathPrefix", UNSET)
 73
 74        _subscribe_mode = d.pop("subscribeMode", UNSET)
 75        subscribe_mode: Union[Unset, ComponentOptionsRecordingSubscribeMode]
 76        if isinstance(_subscribe_mode, Unset):
 77            subscribe_mode = UNSET
 78        else:
 79            subscribe_mode = ComponentOptionsRecordingSubscribeMode(_subscribe_mode)
 80
 81        component_options_recording = cls(
 82            credentials=credentials,
 83            path_prefix=path_prefix,
 84            subscribe_mode=subscribe_mode,
 85        )
 86
 87        component_options_recording.additional_properties = d
 88        return component_options_recording
 89
 90    @property
 91    def additional_keys(self) -> List[str]:
 92        """@private"""
 93        return list(self.additional_properties.keys())
 94
 95    def __getitem__(self, key: str) -> Any:
 96        return self.additional_properties[key]
 97
 98    def __setitem__(self, key: str, value: Any) -> None:
 99        self.additional_properties[key] = value
100
101    def __delitem__(self, key: str) -> None:
102        del self.additional_properties[key]
103
104    def __contains__(self, key: str) -> bool:
105        return key in self.additional_properties

Options specific to the Recording component

ComponentOptionsRecording( credentials: Union[jellyfish._openapi_client.types.Unset, NoneType, S3Credentials] = <jellyfish._openapi_client.types.Unset object>, path_prefix: Union[jellyfish._openapi_client.types.Unset, NoneType, str] = <jellyfish._openapi_client.types.Unset object>, subscribe_mode: Union[jellyfish._openapi_client.types.Unset, ComponentOptionsRecordingSubscribeMode] = <ComponentOptionsRecordingSubscribeMode.AUTO: 'auto'>)
2def __init__(self, credentials=attr_dict['credentials'].default, path_prefix=attr_dict['path_prefix'].default, subscribe_mode=attr_dict['subscribe_mode'].default):
3    self.credentials = credentials
4    self.path_prefix = path_prefix
5    self.subscribe_mode = subscribe_mode
6    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentOptionsRecording.

credentials: Union[jellyfish._openapi_client.types.Unset, NoneType, S3Credentials]

An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided

path_prefix: Union[jellyfish._openapi_client.types.Unset, NoneType, str]

Path prefix under which all recording are stored

subscribe_mode: Union[jellyfish._openapi_client.types.Unset, ComponentOptionsRecordingSubscribeMode]

Whether the Recording component should subscribe to tracks automatically or manually.

class ComponentOptionsRecordingSubscribeMode(builtins.str, enum.Enum):
 5class ComponentOptionsRecordingSubscribeMode(str, Enum):
 6    """Whether the Recording component should subscribe to tracks automatically or manually."""
 7
 8    AUTO = "auto"
 9    MANUAL = "manual"
10
11    def __str__(self) -> str:
12        return str(self.value)

Whether the Recording component should subscribe to tracks automatically or manually.

Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class ComponentPropertiesRecording:
14@_attrs_define
15class ComponentPropertiesRecording:
16    """Properties specific to the Recording component"""
17
18    subscribe_mode: ComponentPropertiesRecordingSubscribeMode
19    """Whether the Recording component should subscribe to tracks automatically or manually"""
20    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
21    """@private"""
22
23    def to_dict(self) -> Dict[str, Any]:
24        """@private"""
25        subscribe_mode = self.subscribe_mode.value
26
27        field_dict: Dict[str, Any] = {}
28        field_dict.update(self.additional_properties)
29        field_dict.update(
30            {
31                "subscribeMode": subscribe_mode,
32            }
33        )
34
35        return field_dict
36
37    @classmethod
38    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
39        """@private"""
40        d = src_dict.copy()
41        subscribe_mode = ComponentPropertiesRecordingSubscribeMode(
42            d.pop("subscribeMode")
43        )
44
45        component_properties_recording = cls(
46            subscribe_mode=subscribe_mode,
47        )
48
49        component_properties_recording.additional_properties = d
50        return component_properties_recording
51
52    @property
53    def additional_keys(self) -> List[str]:
54        """@private"""
55        return list(self.additional_properties.keys())
56
57    def __getitem__(self, key: str) -> Any:
58        return self.additional_properties[key]
59
60    def __setitem__(self, key: str, value: Any) -> None:
61        self.additional_properties[key] = value
62
63    def __delitem__(self, key: str) -> None:
64        del self.additional_properties[key]
65
66    def __contains__(self, key: str) -> bool:
67        return key in self.additional_properties

Properties specific to the Recording component

ComponentPropertiesRecording( subscribe_mode: ComponentPropertiesRecordingSubscribeMode)
2def __init__(self, subscribe_mode):
3    self.subscribe_mode = subscribe_mode
4    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class ComponentPropertiesRecording.

Whether the Recording component should subscribe to tracks automatically or manually

class ComponentPropertiesRecordingSubscribeMode(builtins.str, enum.Enum):
 5class ComponentPropertiesRecordingSubscribeMode(str, Enum):
 6    """Whether the Recording component should subscribe to tracks automatically or manually"""
 7
 8    AUTO = "auto"
 9    MANUAL = "manual"
10
11    def __str__(self) -> str:
12        return str(self.value)

Whether the Recording component should subscribe to tracks automatically or manually

Inherited Members
enum.Enum
name
value
builtins.str
encode
replace
split
rsplit
join
capitalize
casefold
title
center
count
expandtabs
find
partition
index
ljust
lower
lstrip
rfind
rindex
rjust
rstrip
rpartition
splitlines
strip
swapcase
translate
upper
startswith
endswith
removeprefix
removesuffix
isascii
islower
isupper
istitle
isspace
isdecimal
isdigit
isnumeric
isalpha
isalnum
isidentifier
isprintable
zfill
format
format_map
maketrans
class S3Credentials:
10@_attrs_define
11class S3Credentials:
12    """An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are
13    provided
14
15    """
16
17    access_key_id: str
18    """An AWS access key identifier, linked to your AWS account."""
19    bucket: str
20    """The name of the S3 bucket where your data will be stored."""
21    region: str
22    """The AWS region where your bucket is located."""
23    secret_access_key: str
24    """The secret key that is linked to the Access Key ID."""
25    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
26    """@private"""
27
28    def to_dict(self) -> Dict[str, Any]:
29        """@private"""
30        access_key_id = self.access_key_id
31        bucket = self.bucket
32        region = self.region
33        secret_access_key = self.secret_access_key
34
35        field_dict: Dict[str, Any] = {}
36        field_dict.update(self.additional_properties)
37        field_dict.update(
38            {
39                "accessKeyId": access_key_id,
40                "bucket": bucket,
41                "region": region,
42                "secretAccessKey": secret_access_key,
43            }
44        )
45
46        return field_dict
47
48    @classmethod
49    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
50        """@private"""
51        d = src_dict.copy()
52        access_key_id = d.pop("accessKeyId")
53
54        bucket = d.pop("bucket")
55
56        region = d.pop("region")
57
58        secret_access_key = d.pop("secretAccessKey")
59
60        s3_credentials = cls(
61            access_key_id=access_key_id,
62            bucket=bucket,
63            region=region,
64            secret_access_key=secret_access_key,
65        )
66
67        s3_credentials.additional_properties = d
68        return s3_credentials
69
70    @property
71    def additional_keys(self) -> List[str]:
72        """@private"""
73        return list(self.additional_properties.keys())
74
75    def __getitem__(self, key: str) -> Any:
76        return self.additional_properties[key]
77
78    def __setitem__(self, key: str, value: Any) -> None:
79        self.additional_properties[key] = value
80
81    def __delitem__(self, key: str) -> None:
82        del self.additional_properties[key]
83
84    def __contains__(self, key: str) -> bool:
85        return key in self.additional_properties

An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided

S3Credentials(access_key_id: str, bucket: str, region: str, secret_access_key: str)
2def __init__(self, access_key_id, bucket, region, secret_access_key):
3    self.access_key_id = access_key_id
4    self.bucket = bucket
5    self.region = region
6    self.secret_access_key = secret_access_key
7    self.additional_properties = __attr_factory_additional_properties()

Method generated by attrs for class S3Credentials.

access_key_id: str

An AWS access key identifier, linked to your AWS account.

bucket: str

The name of the S3 bucket where your data will be stored.

region: str

The AWS region where your bucket is located.

secret_access_key: str

The secret key that is linked to the Access Key ID.