Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file component #24

Merged
merged 6 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
- run:
name: Lint
command: poetry run lint
- run:
name: Check format
command: poetry run format_check
- persist_to_workspace:
root: ~/project
paths:
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ 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
```console
Expand Down
2 changes: 2 additions & 0 deletions docker-compose-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ services:
- "5002:5002"
- "49999:49999"
- "50000-50050:50000-50050/udp"
volumes:
- ./tests/fixtures:/app/jellyfish_resources/file_component_sources

test:
container_name: test
Expand Down
6 changes: 6 additions & 0 deletions jellyfish/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@

# Models
from jellyfish._openapi_client.models import (
ComponentFile,
ComponentHLS,
ComponentOptionsFile,
ComponentOptionsHLS,
ComponentOptionsHLSSubscribeMode,
ComponentOptionsRTSP,
ComponentPropertiesFile,
ComponentPropertiesHLS,
ComponentPropertiesHLSSubscribeMode,
ComponentPropertiesRTSP,
Expand Down Expand Up @@ -50,6 +53,9 @@
"ComponentRTSP",
"ComponentOptionsRTSP",
"ComponentPropertiesRTSP",
"ComponentFile",
"ComponentOptionsFile",
"ComponentPropertiesFile",
"events",
"errors",
]
Expand Down
2 changes: 2 additions & 0 deletions jellyfish/_openapi_client/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .component_options_hls import ComponentOptionsHLS
from .component_options_hls_subscribe_mode import ComponentOptionsHLSSubscribeMode
from .component_options_rtsp import ComponentOptionsRTSP
from .component_properties_file import ComponentPropertiesFile
from .component_properties_hls import ComponentPropertiesHLS
from .component_properties_hls_subscribe_mode import ComponentPropertiesHLSSubscribeMode
from .component_properties_rtsp import ComponentPropertiesRTSP
Expand Down Expand Up @@ -40,6 +41,7 @@
"ComponentOptionsHLS",
"ComponentOptionsHLSSubscribeMode",
"ComponentOptionsRTSP",
"ComponentPropertiesFile",
"ComponentPropertiesHLS",
"ComponentPropertiesHLSSubscribeMode",
"ComponentPropertiesRTSP",
Expand Down
25 changes: 24 additions & 1 deletion jellyfish/_openapi_client/models/component_file.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from typing import Any, Dict, List, Type, TypeVar
from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

if TYPE_CHECKING:
from ..models.component_properties_file import ComponentPropertiesFile


T = TypeVar("T", bound="ComponentFile")


Expand All @@ -14,13 +20,18 @@ class ComponentFile:
"""Assigned component ID"""
type: str
"""Component type"""
properties: Union[Unset, "ComponentPropertiesFile"] = UNSET
"""Properties specific to the File component"""
additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
"""@private"""

def to_dict(self) -> Dict[str, Any]:
"""@private"""
id = self.id
type = self.type
properties: Union[Unset, Dict[str, Any]] = UNSET
if not isinstance(self.properties, Unset):
properties = self.properties.to_dict()

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
Expand All @@ -30,20 +41,32 @@ def to_dict(self) -> Dict[str, Any]:
"type": type,
}
)
if properties is not UNSET:
field_dict["properties"] = properties

return field_dict

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
"""@private"""
from ..models.component_properties_file import ComponentPropertiesFile

d = src_dict.copy()
id = d.pop("id")

type = d.pop("type")

_properties = d.pop("properties", UNSET)
properties: Union[Unset, ComponentPropertiesFile]
if isinstance(_properties, Unset):
properties = UNSET
else:
properties = ComponentPropertiesFile.from_dict(_properties)

component_file = cls(
id=id,
type=type,
properties=properties,
)

component_file.additional_properties = d
Expand Down
60 changes: 60 additions & 0 deletions jellyfish/_openapi_client/models/component_properties_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from typing import Any, Dict, List, Type, TypeVar

from attrs import define as _attrs_define
from attrs import field as _attrs_field

T = TypeVar("T", bound="ComponentPropertiesFile")


@_attrs_define
class ComponentPropertiesFile:
"""Properties specific to the File component"""

file_path: str
"""Path to track file. Must be either OPUS encapsulated in Ogg or raw h264"""
additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
"""@private"""

def to_dict(self) -> Dict[str, Any]:
"""@private"""
file_path = self.file_path

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"filePath": file_path,
}
)

return field_dict

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
"""@private"""
d = src_dict.copy()
file_path = d.pop("filePath")

component_properties_file = cls(
file_path=file_path,
)

component_properties_file.additional_properties = d
return component_properties_file

@property
def additional_keys(self) -> List[str]:
"""@private"""
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
51 changes: 48 additions & 3 deletions jellyfish/_openapi_client/models/component_properties_rtsp.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,77 @@
from typing import Any, Dict, List, Type, TypeVar
from typing import Any, Dict, List, Type, TypeVar, Union

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

T = TypeVar("T", bound="ComponentPropertiesRTSP")


@_attrs_define
class ComponentPropertiesRTSP:
"""Properties specific to the RTSP component"""

source_uri: str
"""URI of RTSP source stream"""
keep_alive_interval: Union[Unset, int] = UNSET
"""Interval (in ms) in which keep-alive RTSP messages will be sent to the remote stream source"""
pierce_nat: Union[Unset, bool] = UNSET
"""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[Unset, int] = UNSET
"""Delay (in ms) between successive reconnect attempts"""
rtp_port: Union[Unset, int] = UNSET
"""Local port RTP stream will be received at"""
additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)
"""@private"""

def to_dict(self) -> Dict[str, Any]:
"""@private"""
source_uri = self.source_uri
keep_alive_interval = self.keep_alive_interval
pierce_nat = self.pierce_nat
reconnect_delay = self.reconnect_delay
rtp_port = self.rtp_port

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
field_dict.update(
{
"sourceUri": source_uri,
}
)
if keep_alive_interval is not UNSET:
field_dict["keepAliveInterval"] = keep_alive_interval
if pierce_nat is not UNSET:
field_dict["pierceNat"] = pierce_nat
if reconnect_delay is not UNSET:
field_dict["reconnectDelay"] = reconnect_delay
if rtp_port is not UNSET:
field_dict["rtpPort"] = rtp_port

return field_dict

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
"""@private"""
d = src_dict.copy()
component_properties_rtsp = cls()
source_uri = d.pop("sourceUri")

keep_alive_interval = d.pop("keepAliveInterval", UNSET)

pierce_nat = d.pop("pierceNat", UNSET)

reconnect_delay = d.pop("reconnectDelay", UNSET)

rtp_port = d.pop("rtpPort", UNSET)

component_properties_rtsp = cls(
source_uri=source_uri,
keep_alive_interval=keep_alive_interval,
pierce_nat=pierce_nat,
reconnect_delay=reconnect_delay,
rtp_port=rtp_port,
)

component_properties_rtsp.additional_properties = d
return component_properties_rtsp
Expand Down
15 changes: 11 additions & 4 deletions jellyfish/api/_room_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
from jellyfish._openapi_client.models import (
AddComponentJsonBody,
AddPeerJsonBody,
ComponentFile,
ComponentHLS,
ComponentOptionsFile,
ComponentOptionsHLS,
ComponentOptionsRTSP,
ComponentRTSP,
Expand Down Expand Up @@ -119,17 +121,22 @@ def delete_peer(self, room_id: str, peer_id: str) -> None:
return self._request(room_delete_peer, id=peer_id, room_id=room_id)

def add_component(
self, room_id: str, options: Union[ComponentOptionsHLS, ComponentOptionsRTSP]
) -> Union[ComponentHLS, ComponentRTSP]:
self,
room_id: str,
options: Union[ComponentOptionsFile, ComponentOptionsHLS, ComponentOptionsRTSP],
) -> Union[ComponentFile, ComponentHLS, ComponentRTSP]:
"""Creates component in the room"""

if isinstance(options, ComponentOptionsHLS):
if isinstance(options, ComponentOptionsFile):
component_type = "file"
elif isinstance(options, ComponentOptionsHLS):
component_type = "hls"
elif isinstance(options, ComponentOptionsRTSP):
component_type = "rtsp"
else:
raise ValueError(
"options must be either ComponentOptionsHLS or ComponentOptionsRTSP"
"options must be ComponentFile, ComponentOptionsHLS"
"or ComponentOptionsRTSP"
)
Rados13 marked this conversation as resolved.
Show resolved Hide resolved

json_body = AddComponentJsonBody(type=component_type, options=options)
Expand Down
8 changes: 8 additions & 0 deletions poetry_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ def run_tests():
check_exit_code("docker compose -f docker-compose-test.yaml down")


def run_local_test():
check_exit_code('poetry run pytest -m "not file_component_sources"')


def run_formatter():
check_exit_code("ruff format .")


def run_format_check():
check_exit_code("ruff format . --check")


def run_linter():
check_exit_code("ruff check .")

Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
ci_test = "poetry_scripts:run_tests"
local_test = "poetry_scripts:run_local_test"
format = "poetry_scripts:run_formatter"
format_check = "poetry_scripts:run_format_check"
lint = "poetry_scripts:run_linter"
fix_lint = "poetry_scripts:run_linter_fix"
generate_docs = "poetry_scripts:generate_docs"
Expand All @@ -54,3 +56,8 @@ ignore = []

[tool.ruff.extend-per-file-ignores]
"jellyfish/_openapi_client/**" = ["E501"]

[tool.pytest.ini_options]
markers = [
"file_component_sources: Tests requiring files uploaded for File Component"
]
Binary file added tests/fixtures/audio.ogg
Binary file not shown.
Binary file added tests/fixtures/video.h264
Binary file not shown.
Loading