diff --git a/fishjam/_openapi_client/api/recordings/__init__.py b/fishjam/_openapi_client/api/recordings/__init__.py new file mode 100644 index 0000000..2d7c0b2 --- /dev/null +++ b/fishjam/_openapi_client/api/recordings/__init__.py @@ -0,0 +1 @@ +"""Contains endpoint functions for accessing the API""" diff --git a/fishjam/_openapi_client/api/recordings/create_recording.py b/fishjam/_openapi_client/api/recordings/create_recording.py new file mode 100644 index 0000000..ae3507f --- /dev/null +++ b/fishjam/_openapi_client/api/recordings/create_recording.py @@ -0,0 +1,189 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...models.recording_config import RecordingConfig +from ...models.recording_details_response import RecordingDetailsResponse +from ...types import Response + + +def _get_kwargs( + *, + body: RecordingConfig, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/recordings", + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Error | RecordingDetailsResponse | None: + if response.status_code == 201: + response_201 = RecordingDetailsResponse.from_dict(response.json()) + + return response_201 + + if response.status_code == 400: + response_400 = Error.from_dict(response.json()) + + return response_400 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 402: + response_402 = Error.from_dict(response.json()) + + return response_402 + + if response.status_code == 503: + response_503 = Error.from_dict(response.json()) + + return response_503 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[Error | RecordingDetailsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient, + body: RecordingConfig, +) -> Response[Error | RecordingDetailsResponse]: + """Create a recording + + Create a recording resource. Capturing starts synchronously, so it is returned with status `active`. + + Args: + body (RecordingConfig): Recording configuration + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingDetailsResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient, + body: RecordingConfig, +) -> Error | RecordingDetailsResponse | None: + """Create a recording + + Create a recording resource. Capturing starts synchronously, so it is returned with status `active`. + + Args: + body (RecordingConfig): Recording configuration + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingDetailsResponse + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + body: RecordingConfig, +) -> Response[Error | RecordingDetailsResponse]: + """Create a recording + + Create a recording resource. Capturing starts synchronously, so it is returned with status `active`. + + Args: + body (RecordingConfig): Recording configuration + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingDetailsResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient, + body: RecordingConfig, +) -> Error | RecordingDetailsResponse | None: + """Create a recording + + Create a recording resource. Capturing starts synchronously, so it is returned with status `active`. + + Args: + body (RecordingConfig): Recording configuration + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingDetailsResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/fishjam/_openapi_client/api/recordings/delete_recording.py b/fishjam/_openapi_client/api/recordings/delete_recording.py new file mode 100644 index 0000000..cba80de --- /dev/null +++ b/fishjam/_openapi_client/api/recordings/delete_recording.py @@ -0,0 +1,171 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + recording_id: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "delete", + "url": "/recordings/{recording_id}".format( + recording_id=quote(str(recording_id), safe=""), + ), + } + + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Any | Error | None: + if response.status_code == 204: + response_204 = cast(Any, None) + return response_204 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 503: + response_503 = Error.from_dict(response.json()) + + return response_503 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[Any | Error]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Response[Any | Error]: + """Delete a recording + + Delete a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any | Error] + """ + + kwargs = _get_kwargs( + recording_id=recording_id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Any | Error | None: + """Delete a recording + + Delete a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Any | Error + """ + + return sync_detailed( + recording_id=recording_id, + client=client, + ).parsed + + +async def asyncio_detailed( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Response[Any | Error]: + """Delete a recording + + Delete a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any | Error] + """ + + kwargs = _get_kwargs( + recording_id=recording_id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Any | Error | None: + """Delete a recording + + Delete a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Any | Error + """ + + return ( + await asyncio_detailed( + recording_id=recording_id, + client=client, + ) + ).parsed diff --git a/fishjam/_openapi_client/api/recordings/get_recording.py b/fishjam/_openapi_client/api/recordings/get_recording.py new file mode 100644 index 0000000..fff62f1 --- /dev/null +++ b/fishjam/_openapi_client/api/recordings/get_recording.py @@ -0,0 +1,173 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...models.recording_details_response import RecordingDetailsResponse +from ...types import Response + + +def _get_kwargs( + recording_id: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/recordings/{recording_id}".format( + recording_id=quote(str(recording_id), safe=""), + ), + } + + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Error | RecordingDetailsResponse | None: + if response.status_code == 200: + response_200 = RecordingDetailsResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[Error | RecordingDetailsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Response[Error | RecordingDetailsResponse]: + """Get a recording + + Get a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingDetailsResponse] + """ + + kwargs = _get_kwargs( + recording_id=recording_id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Error | RecordingDetailsResponse | None: + """Get a recording + + Get a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingDetailsResponse + """ + + return sync_detailed( + recording_id=recording_id, + client=client, + ).parsed + + +async def asyncio_detailed( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Response[Error | RecordingDetailsResponse]: + """Get a recording + + Get a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingDetailsResponse] + """ + + kwargs = _get_kwargs( + recording_id=recording_id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + recording_id: str, + *, + client: AuthenticatedClient, +) -> Error | RecordingDetailsResponse | None: + """Get a recording + + Get a recording by id. + + Args: + recording_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingDetailsResponse + """ + + return ( + await asyncio_detailed( + recording_id=recording_id, + client=client, + ) + ).parsed diff --git a/fishjam/_openapi_client/api/recordings/list_recordings.py b/fishjam/_openapi_client/api/recordings/list_recordings.py new file mode 100644 index 0000000..b62b930 --- /dev/null +++ b/fishjam/_openapi_client/api/recordings/list_recordings.py @@ -0,0 +1,178 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...models.list_recordings_metadata import ListRecordingsMetadata +from ...models.recording_list_response import RecordingListResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + metadata: ListRecordingsMetadata | Unset = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + json_metadata: dict[str, Any] | Unset = UNSET + if not isinstance(metadata, Unset): + json_metadata = metadata.to_dict() + if not isinstance(json_metadata, Unset): + params.update(json_metadata) + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/recordings", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Error | RecordingListResponse | None: + if response.status_code == 200: + response_200 = RecordingListResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[Error | RecordingListResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient, + metadata: ListRecordingsMetadata | Unset = UNSET, +) -> Response[Error | RecordingListResponse]: + """List recordings + + List recordings for the tenant, optionally filtered by metadata. + + Args: + metadata (ListRecordingsMetadata | Unset): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingListResponse] + """ + + kwargs = _get_kwargs( + metadata=metadata, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient, + metadata: ListRecordingsMetadata | Unset = UNSET, +) -> Error | RecordingListResponse | None: + """List recordings + + List recordings for the tenant, optionally filtered by metadata. + + Args: + metadata (ListRecordingsMetadata | Unset): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingListResponse + """ + + return sync_detailed( + client=client, + metadata=metadata, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + metadata: ListRecordingsMetadata | Unset = UNSET, +) -> Response[Error | RecordingListResponse]: + """List recordings + + List recordings for the tenant, optionally filtered by metadata. + + Args: + metadata (ListRecordingsMetadata | Unset): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Error | RecordingListResponse] + """ + + kwargs = _get_kwargs( + metadata=metadata, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient, + metadata: ListRecordingsMetadata | Unset = UNSET, +) -> Error | RecordingListResponse | None: + """List recordings + + List recordings for the tenant, optionally filtered by metadata. + + Args: + metadata (ListRecordingsMetadata | Unset): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Error | RecordingListResponse + """ + + return ( + await asyncio_detailed( + client=client, + metadata=metadata, + ) + ).parsed diff --git a/fishjam/_openapi_client/api/rooms/add_peer.py b/fishjam/_openapi_client/api/rooms/add_peer.py index 3034664..738ef16 100644 --- a/fishjam/_openapi_client/api/rooms/add_peer.py +++ b/fishjam/_openapi_client/api/rooms/add_peer.py @@ -7,7 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.error import Error -from ...models.peer_config import PeerConfig +from ...models.peer_config_agent import PeerConfigAgent +from ...models.peer_config_vapi import PeerConfigVAPI +from ...models.peer_config_web_rtc import PeerConfigWebRTC from ...models.peer_details_response import PeerDetailsResponse from ...types import UNSET, Response, Unset @@ -15,7 +17,7 @@ def _get_kwargs( room_id: str, *, - body: PeerConfig | Unset = UNSET, + body: PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset = UNSET, ) -> dict[str, Any]: headers: dict[str, Any] = {} @@ -26,7 +28,11 @@ def _get_kwargs( ), } - if not isinstance(body, Unset): + if isinstance(body, PeerConfigWebRTC): + _kwargs["json"] = body.to_dict() + elif isinstance(body, PeerConfigAgent): + _kwargs["json"] = body.to_dict() + else: _kwargs["json"] = body.to_dict() headers["Content-Type"] = "application/json" @@ -94,7 +100,7 @@ def sync_detailed( room_id: str, *, client: AuthenticatedClient, - body: PeerConfig | Unset = UNSET, + body: PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset = UNSET, ) -> Response[Error | PeerDetailsResponse]: """Create a peer @@ -102,7 +108,7 @@ def sync_detailed( Args: room_id (str): - body (PeerConfig | Unset): Peer configuration + body (PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset): Peer configuration Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -128,7 +134,7 @@ def sync( room_id: str, *, client: AuthenticatedClient, - body: PeerConfig | Unset = UNSET, + body: PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset = UNSET, ) -> Error | PeerDetailsResponse | None: """Create a peer @@ -136,7 +142,7 @@ def sync( Args: room_id (str): - body (PeerConfig | Unset): Peer configuration + body (PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset): Peer configuration Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -157,7 +163,7 @@ async def asyncio_detailed( room_id: str, *, client: AuthenticatedClient, - body: PeerConfig | Unset = UNSET, + body: PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset = UNSET, ) -> Response[Error | PeerDetailsResponse]: """Create a peer @@ -165,7 +171,7 @@ async def asyncio_detailed( Args: room_id (str): - body (PeerConfig | Unset): Peer configuration + body (PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset): Peer configuration Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -189,7 +195,7 @@ async def asyncio( room_id: str, *, client: AuthenticatedClient, - body: PeerConfig | Unset = UNSET, + body: PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset = UNSET, ) -> Error | PeerDetailsResponse | None: """Create a peer @@ -197,7 +203,7 @@ async def asyncio( Args: room_id (str): - body (PeerConfig | Unset): Peer configuration + body (PeerConfigAgent | PeerConfigVAPI | PeerConfigWebRTC | Unset): Peer configuration Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. diff --git a/fishjam/_openapi_client/api/streams/create_stream.py b/fishjam/_openapi_client/api/streams/create_stream.py index 4526867..60f6534 100644 --- a/fishjam/_openapi_client/api/streams/create_stream.py +++ b/fishjam/_openapi_client/api/streams/create_stream.py @@ -49,6 +49,11 @@ def _parse_response( return response_401 + if response.status_code == 402: + response_402 = Error.from_dict(response.json()) + + return response_402 + if response.status_code == 503: response_503 = Error.from_dict(response.json()) diff --git a/fishjam/_openapi_client/api/track_forwardings/create_track_forwarding.py b/fishjam/_openapi_client/api/track_forwardings/create_track_forwarding.py index 4468955..5f14f1b 100644 --- a/fishjam/_openapi_client/api/track_forwardings/create_track_forwarding.py +++ b/fishjam/_openapi_client/api/track_forwardings/create_track_forwarding.py @@ -55,6 +55,11 @@ def _parse_response( return response_404 + if response.status_code == 409: + response_409 = Error.from_dict(response.json()) + + return response_409 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: diff --git a/fishjam/_openapi_client/models/__init__.py b/fishjam/_openapi_client/models/__init__.py index 622e2a5..1a8af5f 100644 --- a/fishjam/_openapi_client/models/__init__.py +++ b/fishjam/_openapi_client/models/__init__.py @@ -4,11 +4,18 @@ from .audio_format import AudioFormat from .audio_sample_rate import AudioSampleRate from .composition_info import CompositionInfo +from .composition_source import CompositionSource from .error import Error +from .list_recordings_metadata import ListRecordingsMetadata from .moq_access import MoqAccess from .moq_access_config import MoqAccessConfig from .peer import Peer -from .peer_config import PeerConfig +from .peer_config_agent import PeerConfigAgent +from .peer_config_agent_type import PeerConfigAgentType +from .peer_config_vapi import PeerConfigVAPI +from .peer_config_vapi_type import PeerConfigVAPIType +from .peer_config_web_rtc import PeerConfigWebRTC +from .peer_config_web_rtc_type import PeerConfigWebRTCType from .peer_details_response import PeerDetailsResponse from .peer_details_response_data import PeerDetailsResponseData from .peer_metadata import PeerMetadata @@ -19,6 +26,13 @@ from .peer_refresh_token_response_data import PeerRefreshTokenResponseData from .peer_status import PeerStatus from .peer_type import PeerType +from .recording import Recording +from .recording_config import RecordingConfig +from .recording_config_metadata_type_0 import RecordingConfigMetadataType0 +from .recording_details_response import RecordingDetailsResponse +from .recording_list_response import RecordingListResponse +from .recording_metadata_type_0 import RecordingMetadataType0 +from .recording_status import RecordingStatus from .room import Room from .room_config import RoomConfig from .room_create_details_response import RoomCreateDetailsResponse @@ -53,11 +67,18 @@ "AudioFormat", "AudioSampleRate", "CompositionInfo", + "CompositionSource", "Error", + "ListRecordingsMetadata", "MoqAccess", "MoqAccessConfig", "Peer", - "PeerConfig", + "PeerConfigAgent", + "PeerConfigAgentType", + "PeerConfigVAPI", + "PeerConfigVAPIType", + "PeerConfigWebRTC", + "PeerConfigWebRTCType", "PeerDetailsResponse", "PeerDetailsResponseData", "PeerMetadata", @@ -68,6 +89,13 @@ "PeerRefreshTokenResponseData", "PeerStatus", "PeerType", + "Recording", + "RecordingConfig", + "RecordingConfigMetadataType0", + "RecordingDetailsResponse", + "RecordingListResponse", + "RecordingMetadataType0", + "RecordingStatus", "Room", "RoomConfig", "RoomCreateDetailsResponse", diff --git a/fishjam/_openapi_client/models/composition_source.py b/fishjam/_openapi_client/models/composition_source.py new file mode 100644 index 0000000..2060980 --- /dev/null +++ b/fishjam/_openapi_client/models/composition_source.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CompositionSource") + + +@_attrs_define +class CompositionSource: + """Recording source coming from composition + + Attributes: + composition_url (str): URL of the composition to record + output_id (str): Id of the output being recorded + scale_ratio (float | Unset): Scale factor for the recording relative to the source output (>0; may upscale or + downscale). Defaults to 1. Default: 1.0. + """ + + composition_url: str + output_id: str + scale_ratio: float | Unset = 1.0 + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + composition_url = self.composition_url + + output_id = self.output_id + + scale_ratio = self.scale_ratio + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "compositionURL": composition_url, + "outputId": output_id, + }) + if scale_ratio is not UNSET: + field_dict["scaleRatio"] = scale_ratio + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + composition_url = d.pop("compositionURL") + + output_id = d.pop("outputId") + + scale_ratio = d.pop("scaleRatio", UNSET) + + composition_source = cls( + composition_url=composition_url, + output_id=output_id, + scale_ratio=scale_ratio, + ) + + composition_source.additional_properties = d + return composition_source + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/list_recordings_metadata.py b/fishjam/_openapi_client/models/list_recordings_metadata.py new file mode 100644 index 0000000..0ba5136 --- /dev/null +++ b/fishjam/_openapi_client/models/list_recordings_metadata.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ListRecordingsMetadata") + + +@_attrs_define +class ListRecordingsMetadata: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + list_recordings_metadata = cls() + + list_recordings_metadata.additional_properties = d + return list_recordings_metadata + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/peer_config.py b/fishjam/_openapi_client/models/peer_config.py deleted file mode 100644 index eccbfea..0000000 --- a/fishjam/_openapi_client/models/peer_config.py +++ /dev/null @@ -1,98 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define - -from ..models.peer_type import PeerType - -if TYPE_CHECKING: - from ..models.peer_options_agent import PeerOptionsAgent - from ..models.peer_options_vapi import PeerOptionsVapi - from ..models.peer_options_web_rtc import PeerOptionsWebRTC - - -T = TypeVar("T", bound="PeerConfig") - - -@_attrs_define -class PeerConfig: - """Peer configuration - - Attributes: - options (PeerOptionsAgent | PeerOptionsVapi | PeerOptionsWebRTC): Peer-specific options - type_ (PeerType): Peer type Example: webrtc. - """ - - options: PeerOptionsAgent | PeerOptionsVapi | PeerOptionsWebRTC - type_: PeerType - - def to_dict(self) -> dict[str, Any]: - from ..models.peer_options_agent import PeerOptionsAgent - from ..models.peer_options_web_rtc import PeerOptionsWebRTC - - options: dict[str, Any] - if isinstance(self.options, PeerOptionsWebRTC): - options = self.options.to_dict() - elif isinstance(self.options, PeerOptionsAgent): - options = self.options.to_dict() - else: - options = self.options.to_dict() - - type_ = self.type_.value - - field_dict: dict[str, Any] = {} - - field_dict.update({ - "options": options, - "type": type_, - }) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.peer_options_agent import PeerOptionsAgent - from ..models.peer_options_vapi import PeerOptionsVapi - from ..models.peer_options_web_rtc import PeerOptionsWebRTC - - d = dict(src_dict) - - def _parse_options( - data: object, - ) -> PeerOptionsAgent | PeerOptionsVapi | PeerOptionsWebRTC: - try: - if not isinstance(data, dict): - raise TypeError() - componentsschemas_peer_options_type_0 = PeerOptionsWebRTC.from_dict( - data - ) - - return componentsschemas_peer_options_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - try: - if not isinstance(data, dict): - raise TypeError() - componentsschemas_peer_options_type_1 = PeerOptionsAgent.from_dict(data) - - return componentsschemas_peer_options_type_1 - except (TypeError, ValueError, AttributeError, KeyError): - pass - if not isinstance(data, dict): - raise TypeError() - componentsschemas_peer_options_type_2 = PeerOptionsVapi.from_dict(data) - - return componentsschemas_peer_options_type_2 - - options = _parse_options(d.pop("options")) - - type_ = PeerType(d.pop("type")) - - peer_config = cls( - options=options, - type_=type_, - ) - - return peer_config diff --git a/fishjam/_openapi_client/models/peer_config_agent.py b/fishjam/_openapi_client/models/peer_config_agent.py new file mode 100644 index 0000000..3df274a --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_agent.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define + +from ..models.peer_config_agent_type import PeerConfigAgentType + +if TYPE_CHECKING: + from ..models.peer_options_agent import PeerOptionsAgent + + +T = TypeVar("T", bound="PeerConfigAgent") + + +@_attrs_define +class PeerConfigAgent: + """Configuration of an agent peer + + Attributes: + options (PeerOptionsAgent): Options specific to the Agent peer + type_ (PeerConfigAgentType): Peer type + """ + + options: PeerOptionsAgent + type_: PeerConfigAgentType + + def to_dict(self) -> dict[str, Any]: + options = self.options.to_dict() + + type_ = self.type_.value + + field_dict: dict[str, Any] = {} + + field_dict.update({ + "options": options, + "type": type_, + }) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.peer_options_agent import PeerOptionsAgent + + d = dict(src_dict) + options = PeerOptionsAgent.from_dict(d.pop("options")) + + type_ = PeerConfigAgentType(d.pop("type")) + + peer_config_agent = cls( + options=options, + type_=type_, + ) + + return peer_config_agent diff --git a/fishjam/_openapi_client/models/peer_config_agent_type.py b/fishjam/_openapi_client/models/peer_config_agent_type.py new file mode 100644 index 0000000..cb8343f --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_agent_type.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class PeerConfigAgentType(str, Enum): + """Peer type""" + + AGENT = "agent" + + def __str__(self) -> str: + return str(self.value) diff --git a/fishjam/_openapi_client/models/peer_config_vapi.py b/fishjam/_openapi_client/models/peer_config_vapi.py new file mode 100644 index 0000000..3869828 --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_vapi.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define + +from ..models.peer_config_vapi_type import PeerConfigVAPIType + +if TYPE_CHECKING: + from ..models.peer_options_vapi import PeerOptionsVapi + + +T = TypeVar("T", bound="PeerConfigVAPI") + + +@_attrs_define +class PeerConfigVAPI: + """Configuration of a VAPI peer + + Attributes: + options (PeerOptionsVapi): Options specific to the VAPI peer + type_ (PeerConfigVAPIType): Peer type + """ + + options: PeerOptionsVapi + type_: PeerConfigVAPIType + + def to_dict(self) -> dict[str, Any]: + options = self.options.to_dict() + + type_ = self.type_.value + + field_dict: dict[str, Any] = {} + + field_dict.update({ + "options": options, + "type": type_, + }) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.peer_options_vapi import PeerOptionsVapi + + d = dict(src_dict) + options = PeerOptionsVapi.from_dict(d.pop("options")) + + type_ = PeerConfigVAPIType(d.pop("type")) + + peer_config_vapi = cls( + options=options, + type_=type_, + ) + + return peer_config_vapi diff --git a/fishjam/_openapi_client/models/peer_config_vapi_type.py b/fishjam/_openapi_client/models/peer_config_vapi_type.py new file mode 100644 index 0000000..d023956 --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_vapi_type.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class PeerConfigVAPIType(str, Enum): + """Peer type""" + + VAPI = "vapi" + + def __str__(self) -> str: + return str(self.value) diff --git a/fishjam/_openapi_client/models/peer_config_web_rtc.py b/fishjam/_openapi_client/models/peer_config_web_rtc.py new file mode 100644 index 0000000..207b8d4 --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_web_rtc.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define + +from ..models.peer_config_web_rtc_type import PeerConfigWebRTCType + +if TYPE_CHECKING: + from ..models.peer_options_web_rtc import PeerOptionsWebRTC + + +T = TypeVar("T", bound="PeerConfigWebRTC") + + +@_attrs_define +class PeerConfigWebRTC: + """Configuration of a webrtc peer + + Attributes: + options (PeerOptionsWebRTC): Options specific to the WebRTC peer + type_ (PeerConfigWebRTCType): Peer type + """ + + options: PeerOptionsWebRTC + type_: PeerConfigWebRTCType + + def to_dict(self) -> dict[str, Any]: + options = self.options.to_dict() + + type_ = self.type_.value + + field_dict: dict[str, Any] = {} + + field_dict.update({ + "options": options, + "type": type_, + }) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.peer_options_web_rtc import PeerOptionsWebRTC + + d = dict(src_dict) + options = PeerOptionsWebRTC.from_dict(d.pop("options")) + + type_ = PeerConfigWebRTCType(d.pop("type")) + + peer_config_web_rtc = cls( + options=options, + type_=type_, + ) + + return peer_config_web_rtc diff --git a/fishjam/_openapi_client/models/peer_config_web_rtc_type.py b/fishjam/_openapi_client/models/peer_config_web_rtc_type.py new file mode 100644 index 0000000..ff0a764 --- /dev/null +++ b/fishjam/_openapi_client/models/peer_config_web_rtc_type.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class PeerConfigWebRTCType(str, Enum): + """Peer type""" + + WEBRTC = "webrtc" + + def __str__(self) -> str: + return str(self.value) diff --git a/fishjam/_openapi_client/models/recording.py b/fishjam/_openapi_client/models/recording.py new file mode 100644 index 0000000..b4c2c51 --- /dev/null +++ b/fishjam/_openapi_client/models/recording.py @@ -0,0 +1,120 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..models.recording_status import RecordingStatus +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.composition_source import CompositionSource + from ..models.recording_metadata_type_0 import RecordingMetadataType0 + + +T = TypeVar("T", bound="Recording") + + +@_attrs_define +class Recording: + """A recording and its current lifecycle status + + Attributes: + id (str): Assigned recording id + source (CompositionSource): Recording source coming from composition + status (RecordingStatus): Lifecycle status of a recording + metadata (None | RecordingMetadataType0 | Unset): Free-form, user-supplied metadata used to organize and filter + recordings + """ + + id: str + source: CompositionSource + status: RecordingStatus + metadata: None | RecordingMetadataType0 | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + from ..models.recording_metadata_type_0 import RecordingMetadataType0 + + id = self.id + + source = self.source.to_dict() + + status = self.status.value + + metadata: dict[str, Any] | None | Unset + if isinstance(self.metadata, Unset): + metadata = UNSET + elif isinstance(self.metadata, RecordingMetadataType0): + metadata = self.metadata.to_dict() + else: + metadata = self.metadata + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "id": id, + "source": source, + "status": status, + }) + if metadata is not UNSET: + field_dict["metadata"] = metadata + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.composition_source import CompositionSource + from ..models.recording_metadata_type_0 import RecordingMetadataType0 + + d = dict(src_dict) + id = d.pop("id") + + source = CompositionSource.from_dict(d.pop("source")) + + status = RecordingStatus(d.pop("status")) + + def _parse_metadata(data: object) -> None | RecordingMetadataType0 | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + metadata_type_0 = RecordingMetadataType0.from_dict(data) + + return metadata_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | RecordingMetadataType0 | Unset, data) + + metadata = _parse_metadata(d.pop("metadata", UNSET)) + + recording = cls( + id=id, + source=source, + status=status, + metadata=metadata, + ) + + recording.additional_properties = d + return recording + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/recording_config.py b/fishjam/_openapi_client/models/recording_config.py new file mode 100644 index 0000000..689fcd8 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_config.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, cast + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.composition_source import CompositionSource + from ..models.recording_config_metadata_type_0 import RecordingConfigMetadataType0 + + +T = TypeVar("T", bound="RecordingConfig") + + +@_attrs_define +class RecordingConfig: + """Recording configuration + + Attributes: + source (CompositionSource): Recording source coming from composition + metadata (None | RecordingConfigMetadataType0 | Unset): Free-form, user-supplied metadata used to organize and + filter recordings + """ + + source: CompositionSource + metadata: None | RecordingConfigMetadataType0 | Unset = UNSET + + def to_dict(self) -> dict[str, Any]: + from ..models.recording_config_metadata_type_0 import ( + RecordingConfigMetadataType0, + ) + + source = self.source.to_dict() + + metadata: dict[str, Any] | None | Unset + if isinstance(self.metadata, Unset): + metadata = UNSET + elif isinstance(self.metadata, RecordingConfigMetadataType0): + metadata = self.metadata.to_dict() + else: + metadata = self.metadata + + field_dict: dict[str, Any] = {} + + field_dict.update({ + "source": source, + }) + if metadata is not UNSET: + field_dict["metadata"] = metadata + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.composition_source import CompositionSource + from ..models.recording_config_metadata_type_0 import ( + RecordingConfigMetadataType0, + ) + + d = dict(src_dict) + source = CompositionSource.from_dict(d.pop("source")) + + def _parse_metadata( + data: object, + ) -> None | RecordingConfigMetadataType0 | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + metadata_type_0 = RecordingConfigMetadataType0.from_dict(data) + + return metadata_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | RecordingConfigMetadataType0 | Unset, data) + + metadata = _parse_metadata(d.pop("metadata", UNSET)) + + recording_config = cls( + source=source, + metadata=metadata, + ) + + return recording_config diff --git a/fishjam/_openapi_client/models/recording_config_metadata_type_0.py b/fishjam/_openapi_client/models/recording_config_metadata_type_0.py new file mode 100644 index 0000000..36e7ef1 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_config_metadata_type_0.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="RecordingConfigMetadataType0") + + +@_attrs_define +class RecordingConfigMetadataType0: + """Free-form, user-supplied metadata used to organize and filter recordings""" + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + recording_config_metadata_type_0 = cls() + + recording_config_metadata_type_0.additional_properties = d + return recording_config_metadata_type_0 + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/recording_details_response.py b/fishjam/_openapi_client/models/recording_details_response.py new file mode 100644 index 0000000..abc9d60 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_details_response.py @@ -0,0 +1,66 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +if TYPE_CHECKING: + from ..models.recording import Recording + + +T = TypeVar("T", bound="RecordingDetailsResponse") + + +@_attrs_define +class RecordingDetailsResponse: + """Response containing recording details + + Attributes: + data (Recording): A recording and its current lifecycle status + """ + + data: Recording + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data = self.data.to_dict() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "data": data, + }) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.recording import Recording + + d = dict(src_dict) + data = Recording.from_dict(d.pop("data")) + + recording_details_response = cls( + data=data, + ) + + recording_details_response.additional_properties = d + return recording_details_response + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/recording_list_response.py b/fishjam/_openapi_client/models/recording_list_response.py new file mode 100644 index 0000000..85c23c1 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_list_response.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +if TYPE_CHECKING: + from ..models.recording import Recording + + +T = TypeVar("T", bound="RecordingListResponse") + + +@_attrs_define +class RecordingListResponse: + """Response containing list of recordings + + Attributes: + data (list[Recording]): + """ + + data: list[Recording] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data = [] + for data_item_data in self.data: + data_item = data_item_data.to_dict() + data.append(data_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "data": data, + }) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.recording import Recording + + d = dict(src_dict) + data = [] + _data = d.pop("data") + for data_item_data in _data: + data_item = Recording.from_dict(data_item_data) + + data.append(data_item) + + recording_list_response = cls( + data=data, + ) + + recording_list_response.additional_properties = d + return recording_list_response + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/recording_metadata_type_0.py b/fishjam/_openapi_client/models/recording_metadata_type_0.py new file mode 100644 index 0000000..67045c1 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_metadata_type_0.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="RecordingMetadataType0") + + +@_attrs_define +class RecordingMetadataType0: + """Free-form, user-supplied metadata used to organize and filter recordings""" + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + recording_metadata_type_0 = cls() + + recording_metadata_type_0.additional_properties = d + return recording_metadata_type_0 + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/fishjam/_openapi_client/models/recording_status.py b/fishjam/_openapi_client/models/recording_status.py new file mode 100644 index 0000000..60da974 --- /dev/null +++ b/fishjam/_openapi_client/models/recording_status.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class RecordingStatus(str, Enum): + """Lifecycle status of a recording""" + + ACTIVE = "active" + AVAILABLE = "available" + FAILED = "failed" + + def __str__(self) -> str: + return str(self.value) diff --git a/fishjam/_openapi_client/models/room_config.py b/fishjam/_openapi_client/models/room_config.py index f81e6e8..a9c6bfb 100644 --- a/fishjam/_openapi_client/models/room_config.py +++ b/fishjam/_openapi_client/models/room_config.py @@ -24,7 +24,8 @@ class RoomConfig: public (bool | Unset): True if livestream viewers can omit specifying a token. Default: False. room_type (RoomType | Unset): The use-case of the room. If not provided, this defaults to conference. video_codec (VideoCodec | Unset): Enforces video codec for each peer in the room - webhook_url (None | str | Unset): URL where Fishjam notifications will be sent Example: + webhook_url (None | str | Unset): Deprecated: configure the webhook in the Dashboard instead. URL where Fishjam + notifications will be sent; overrides the Dashboard-configured webhook URL Example: https://backend.address.com/fishjam-notifications-endpoint. """ diff --git a/fishjam/_openapi_client/models/stream_config.py b/fishjam/_openapi_client/models/stream_config.py index 7fc366d..94d52b3 100644 --- a/fishjam/_openapi_client/models/stream_config.py +++ b/fishjam/_openapi_client/models/stream_config.py @@ -20,7 +20,8 @@ class StreamConfig: single NotificationBatch per HTTP send instead of one request per notification. VAD notifications are unaffected. Default: False. public (bool | Unset): True if livestream viewers can omit specifying a token. Default: False. - webhook_url (None | str | Unset): Webhook URL for receiving server notifications + webhook_url (None | str | Unset): Deprecated: configure the webhook in the Dashboard instead. Webhook URL for + receiving server notifications; overrides the Dashboard-configured webhook URL """ audio_only: bool | None | Unset = False diff --git a/fishjam/agent/agent.py b/fishjam/agent/agent.py index da4c967..4354e5d 100644 --- a/fishjam/agent/agent.py +++ b/fishjam/agent/agent.py @@ -203,6 +203,7 @@ def __init__(self, id: str, room_id: str, token: str, fishjam_url: str): self.id = id self.room_id = room_id + self._fishjam_url = fishjam_url self._socket_url = f"{fishjam_url}/socket/agent/websocket".replace("http", "ws") self._token = token diff --git a/fishjam/api/_fishjam_client.py b/fishjam/api/_fishjam_client.py index 5f165cb..eddaad6 100644 --- a/fishjam/api/_fishjam_client.py +++ b/fishjam/api/_fishjam_client.py @@ -32,13 +32,17 @@ MoqAccess, MoqAccessConfig, Peer, - PeerConfig, + PeerConfigAgent, + PeerConfigAgentType, + PeerConfigVAPI, + PeerConfigVAPIType, + PeerConfigWebRTC, + PeerConfigWebRTCType, PeerDetailsResponse, PeerOptionsAgent, PeerOptionsVapi, PeerOptionsWebRTC, PeerRefreshTokenResponse, - PeerType, RoomConfig, RoomCreateDetailsResponse, RoomDetailsResponse, @@ -51,7 +55,7 @@ ViewerToken, WebRTCMetadata, ) -from fishjam._openapi_client.types import UNSET +from fishjam._openapi_client.types import UNSET, Unset from fishjam.agent import Agent from fishjam.api._client import Client from fishjam.errors import ( @@ -230,7 +234,7 @@ def create_peer( metadata=peer_metadata, subscribe_mode=SubscribeMode(options.subscribe_mode), ) - body = PeerConfig(type_=PeerType.WEBRTC, options=peer_options) + body = PeerConfigWebRTC(type_=PeerConfigWebRTCType.WEBRTC, options=peer_options) resp = cast( PeerDetailsResponse, @@ -251,8 +255,8 @@ def create_agent(self, room_id: str, options: AgentOptions | None = None): and Fishjam URL. """ options = options or AgentOptions() - body = PeerConfig( - type_=PeerType.AGENT, + body = PeerConfigAgent( + type_=PeerConfigAgentType.AGENT, options=PeerOptionsAgent( output=AgentOutput( audio_format=AudioFormat(options.output.audio_format), @@ -267,7 +271,19 @@ def create_agent(self, room_id: str, options: AgentOptions | None = None): self._request(room_add_peer, room_id=room_id, body=body), ) - return Agent(resp.data.peer.id, room_id, resp.data.token, self._fishjam_url) + socket_base_url = self._peer_socket_base_url(resp.data.peer_websocket_url) + return Agent(resp.data.peer.id, room_id, resp.data.token, socket_base_url) + + def _peer_socket_base_url(self, peer_websocket_url: str | Unset) -> str: + if isinstance(peer_websocket_url, Unset) or not peer_websocket_url: + return self._fishjam_url + + url = peer_websocket_url + if "://" not in url: + url = f"https://{url}" + for suffix in ("/socket/peer/websocket", "/socket/agent/websocket"): + url = url.removesuffix(suffix) + return url def create_vapi_agent( self, @@ -283,7 +299,7 @@ def create_vapi_agent( Returns: - Peer: The created peer object. """ - body = PeerConfig(type_=PeerType.VAPI, options=options) + body = PeerConfigVAPI(type_=PeerConfigVAPIType.VAPI, options=options) resp = cast( PeerDetailsResponse, diff --git a/protos b/protos index 24e6206..50aacf9 160000 --- a/protos +++ b/protos @@ -1 +1 @@ -Subproject commit 24e62066320eb079695c0c571b1c475e82e14ec5 +Subproject commit 50aacf9839c7e1f67e983f775f04206050b99cee diff --git a/pyproject.toml b/pyproject.toml index e3d3a7f..efaac4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "fishjam-server-sdk" -version = "0.28.1" +version = "0.29.0" description = "Python server SDK for the Fishjam" authors = [{ name = "Fishjam Team", email = "contact@fishjam.io" }] requires-python = ">=3.10" diff --git a/tests/agent/test_agent.py b/tests/agent/test_agent.py index 761d622..9b2871c 100644 --- a/tests/agent/test_agent.py +++ b/tests/agent/test_agent.py @@ -105,11 +105,11 @@ async def wait_event(event: asyncio.Event, timeout: float = 5): class TestAgentConnection: @pytest.mark.asyncio - async def test_invalid_auth(self, room_api: FishjamClient): - agent = Agent("fake-id", "room-id", "fake-token", room_api._fishjam_url) + async def test_invalid_auth(self, room: Room, agent: Agent): + bogus_agent = Agent("fake-id", room.id, "fake-token", agent._fishjam_url) with pytest.raises(AgentAuthError): - async with agent.connect(): + async with bogus_agent.connect(): raise RuntimeError("Connect should have raised AgentAuthError.") @pytest.mark.asyncio diff --git a/uv.lock b/uv.lock index 906df31..4e8f3ae 100644 --- a/uv.lock +++ b/uv.lock @@ -679,7 +679,7 @@ wheels = [ [[package]] name = "fishjam-server-sdk" -version = "0.28.1" +version = "0.29.0" source = { editable = "." } dependencies = [ { name = "aenum" },