diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9ed6d7..2295192 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,20 +1,21 @@ repos: - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 26.1.0 hooks: - id: black - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 7.0.0 hooks: - id: isort name: isort args: [--profile, black, --skip, migrations] - repo: https://github.com/pycqa/flake8 - rev: "6.0.0" # pick a git hash / tag to point to + rev: "7.3.0" hooks: - id: flake8 + additional_dependencies: ["pyflakes>=3.2.0"] - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.2.0" + rev: "v1.19.1" hooks: - id: mypy args: [--no-strict-optional, --ignore-missing-imports] diff --git a/.vscode/settings.json b/.vscode/settings.json index f0f682a..df863d7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,10 +24,7 @@ "python.analysis.inlayHints.functionReturnTypes": true, "editor.formatOnSave": true, "isort.check": true, - "isort.args": [ - "--profile", - "black" - ], + "isort.args": ["--profile", "black"], "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ "tests", @@ -38,7 +35,7 @@ ], "[python]": { "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "explicit" }, "editor.defaultFormatter": "ms-python.black-formatter", "editor.codeLens": true @@ -50,6 +47,6 @@ "files.exclude": { "**/__pycache__": true, "**/.pytest_cache": true, - "**/.mypy*": true, - }, -} \ No newline at end of file + "**/.mypy*": true + } +} diff --git a/README.md b/README.md index 2e452b2..c7da040 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ setup_logs(log_level=logging.DEBUG) 1. get webinar live stream 2. update webinar live stream -3. update webinar livestream status +3. update webinar livestream status - Following [Zoom documentation](https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetingLiveStreamStatusUpdate). ### **zoom rooms**: diff --git a/example/get_meeting_livestream.py b/example/get_meeting_livestream.py index b225fa1..f4e4079 100644 --- a/example/get_meeting_livestream.py +++ b/example/get_meeting_livestream.py @@ -9,7 +9,5 @@ MEETING_ID = os.environ["MEETING_ID"] -result = zoom_client.meeting_livestreams.get_livestream( - MEETING_ID, -) +result = zoom_client.meeting_livestreams.get_livestream(MEETING_ID) print(result) diff --git a/example/get_rooms.py b/example/get_rooms.py index adbe573..298ac2e 100644 --- a/example/get_rooms.py +++ b/example/get_rooms.py @@ -9,7 +9,9 @@ logger = setup_logs(log_level=logging.DEBUG) -zoom_client = ZoomApiClient.init_from_dotenv(use_path=".") +zoom_client = ZoomApiClient.init_from_dotenv( + use_path="." +) parameters = RoomsListDict( type=RoomType.ZOOM_ROOM, diff --git a/example/start_meeting_livestream.py b/example/start_meeting_livestream.py new file mode 100644 index 0000000..a91c8e3 --- /dev/null +++ b/example/start_meeting_livestream.py @@ -0,0 +1,26 @@ +import logging +import os + +from zoom_python_client.utils.logger import setup_logs +from zoom_python_client.zoom_api_client import ZoomApiClient + +setup_logs(log_level=logging.DEBUG) +zoom_client = ZoomApiClient.init_from_dotenv() +MEETING_ID = os.environ["MEETING_ID"] + + +result = zoom_client.meeting_livestreams.get_livestream(MEETING_ID) +print(result) + +settings = { + "active_speaker_name": False, + "display_name": "CERN_Webcast_Service", + "layout": "follow_host", + "close_caption": "embedded", +} +started = zoom_client.meeting_livestreams.update_livestream_status( + MEETING_ID, + "start", + settings=settings, +) +print(started) diff --git a/requirements.txt b/requirements.txt index 4deb882..49c3108 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ python-dotenv==1.0.0 requests==2.31.0 -typing_extensions==4.7.1 \ No newline at end of file +typing_extensions==4.7.1 +typed-ast==1.5.5 \ No newline at end of file diff --git a/tests/zoom_python_client/client_components/meeting_livestreams/test_meeting_livestreams_component.py b/tests/zoom_python_client/client_components/meeting_livestreams/test_meeting_livestreams_component.py index f724f21..0e47bea 100644 --- a/tests/zoom_python_client/client_components/meeting_livestreams/test_meeting_livestreams_component.py +++ b/tests/zoom_python_client/client_components/meeting_livestreams/test_meeting_livestreams_component.py @@ -81,14 +81,29 @@ def test_update_meeting_livestreams_component_no_response(self): @responses.activate def test_update_meeting_livestreams_status_component(self): + settings = { + "active_speaker_name": False, + "display_name": "CERN_Webcast_Service", + "layout": "follow_host", + "close_caption": "embedded", + } responses.add( responses.PATCH, "http://localhost/meetings/12345/livestream/status", status=204, + match=[ + responses.matchers.json_params_matcher( + {"action": "start", "settings": settings} + ) + ], ) zoom_client = ZoomApiClient("aaa", "bbb", "ccc", "http://localhost") component = MeetingLiveStreamsComponent(zoom_client) - result = component.update_livestream_status("12345", "start") + result = component.update_livestream_status( + "12345", + "start", + settings=settings, + ) assert result @responses.activate diff --git a/tests/zoom_python_client/client_components/webinar_livestreams/test_webinar_livestreams_component.py b/tests/zoom_python_client/client_components/webinar_livestreams/test_webinar_livestreams_component.py index 2167310..d76acc3 100644 --- a/tests/zoom_python_client/client_components/webinar_livestreams/test_webinar_livestreams_component.py +++ b/tests/zoom_python_client/client_components/webinar_livestreams/test_webinar_livestreams_component.py @@ -81,14 +81,29 @@ def test_update_webinar_livestreams_component_no_response(self): @responses.activate def test_update_webinar_livestreams_status_component(self): + settings = { + "active_speaker_name": False, + "display_name": "CERN_Webcast_Service", + "layout": "follow_host", + "close_caption": "embedded", + } responses.add( responses.PATCH, "http://localhost/webinars/12345/livestream/status", status=204, + match=[ + responses.matchers.json_params_matcher( + {"action": "start", "settings": settings} + ) + ], ) zoom_client = ZoomApiClient("aaa", "bbb", "ccc", "http://localhost") component = WebinarLiveStreamsComponent(zoom_client) - result = component.update_livestream_status("12345", "start") + result = component.update_livestream_status( + "12345", + "start", + settings=settings, + ) assert result @responses.activate diff --git a/zoom_python_client/client_components/meeting_livestreams/meeting_livestreams_component.py b/zoom_python_client/client_components/meeting_livestreams/meeting_livestreams_component.py index 6262c62..23734ad 100644 --- a/zoom_python_client/client_components/meeting_livestreams/meeting_livestreams_component.py +++ b/zoom_python_client/client_components/meeting_livestreams/meeting_livestreams_component.py @@ -1,5 +1,7 @@ from json import JSONDecodeError -from typing import TypedDict +from typing import Any, Dict, Optional + +from typing_extensions import NotRequired, TypedDict from zoom_python_client.zoom_auth_api.zoom_auth_api_client import ZoomAuthApiClientError from zoom_python_client.zoom_client_interface import ZoomClientInterface @@ -14,6 +16,7 @@ class LiveStreamDict(TypedDict): class LiveStreamStatusDict(TypedDict): action: str + settings: NotRequired[Dict[str, Any]] class MeetingLiveStreamsComponent: @@ -41,9 +44,16 @@ def update_livestream(self, meeting_id: str, data: LiveStreamDict) -> bool: return True return False - def update_livestream_status(self, meeting_id: str, action: str) -> bool: + def update_livestream_status( + self, + meeting_id: str, + action: str, + settings: Optional[Dict[str, Any]] = None, + ) -> bool: api_path = f"/meetings/{meeting_id}/livestream/status" data: LiveStreamStatusDict = {"action": action} + if settings is not None: + data["settings"] = settings response = self.client.make_patch_request(api_path, data) if response and response.status_code == 204: return True diff --git a/zoom_python_client/client_components/webinar_livestreams/webinar_livestreams_component.py b/zoom_python_client/client_components/webinar_livestreams/webinar_livestreams_component.py index 9f5b5c8..8702afc 100644 --- a/zoom_python_client/client_components/webinar_livestreams/webinar_livestreams_component.py +++ b/zoom_python_client/client_components/webinar_livestreams/webinar_livestreams_component.py @@ -1,5 +1,7 @@ from json import JSONDecodeError -from typing import TypedDict +from typing import Any, Dict, Optional + +from typing_extensions import NotRequired, TypedDict from zoom_python_client.zoom_auth_api.zoom_auth_api_client import ZoomAuthApiClientError from zoom_python_client.zoom_client_interface import ZoomClientInterface @@ -14,6 +16,7 @@ class LiveStreamDict(TypedDict): class LiveStreamStatusDict(TypedDict): action: str + settings: NotRequired[Dict[str, Any]] class WebinarLiveStreamsComponent: @@ -38,9 +41,16 @@ def update_livestream(self, meeting_id: str, data: LiveStreamDict) -> bool: return True return False - def update_livestream_status(self, meeting_id: str, action: str) -> bool: + def update_livestream_status( + self, + meeting_id: str, + action: str, + settings: Optional[Dict[str, Any]] = None, + ) -> bool: api_path = f"/webinars/{meeting_id}/livestream/status" data: LiveStreamStatusDict = {"action": action} + if settings is not None: + data["settings"] = settings response = self.client.make_patch_request(api_path, data) if response.status_code == 204: return True diff --git a/zoom_python_client/utils/typed_dict_parameters.py b/zoom_python_client/utils/typed_dict_parameters.py index b958304..889762c 100644 --- a/zoom_python_client/utils/typed_dict_parameters.py +++ b/zoom_python_client/utils/typed_dict_parameters.py @@ -6,7 +6,7 @@ class DataType(TypedDict, total=False): - ... + pass def generate_parameters_dict(data: DataType) -> dict: