From 46ccd6fa00373e2369013c16e971bbbd21b52c60 Mon Sep 17 00:00:00 2001 From: Karol Konkol Date: Tue, 28 Nov 2023 16:34:50 +0100 Subject: [PATCH 1/2] Add feature: hls manual track subscription --- jellyfish/_openapi_client/__init__.py | 11 +- jellyfish/_openapi_client/api/__init__.py | 3 +- .../api/{default_api.py => hls_api.py} | 189 ++++++- .../_openapi_client/api/recording_api.py | 484 ++++++++++++++++++ jellyfish/_openapi_client/models/__init__.py | 8 + .../models/component_metadata_hls.py | 23 +- .../models/component_options_hls.py | 43 +- .../models/component_options_hlss3.py | 149 ++++++ .../models/recording_list_response.py | 65 +++ .../_openapi_client/models/s3_credentials.py | 86 ++++ .../models/subscription_config.py | 67 +++ jellyfish/_room_api.py | 6 + tests/test_room_api.py | 17 +- 13 files changed, 1134 insertions(+), 17 deletions(-) rename jellyfish/_openapi_client/api/{default_api.py => hls_api.py} (54%) create mode 100644 jellyfish/_openapi_client/api/recording_api.py create mode 100644 jellyfish/_openapi_client/models/component_options_hlss3.py create mode 100644 jellyfish/_openapi_client/models/recording_list_response.py create mode 100644 jellyfish/_openapi_client/models/s3_credentials.py create mode 100644 jellyfish/_openapi_client/models/subscription_config.py diff --git a/jellyfish/_openapi_client/__init__.py b/jellyfish/_openapi_client/__init__.py index d521219..34855c8 100644 --- a/jellyfish/_openapi_client/__init__.py +++ b/jellyfish/_openapi_client/__init__.py @@ -15,7 +15,8 @@ __version__ = "1.0.0" # import apis into sdk package -from jellyfish._openapi_client.api.default_api import DefaultApi +from jellyfish._openapi_client.api.hls_api import HlsApi +from jellyfish._openapi_client.api.recording_api import RecordingApi from jellyfish._openapi_client.api.room_api import RoomApi # import ApiClient @@ -40,6 +41,9 @@ from jellyfish._openapi_client.models.component_metadata_hls import ComponentMetadataHLS from jellyfish._openapi_client.models.component_options import ComponentOptions from jellyfish._openapi_client.models.component_options_hls import ComponentOptionsHLS +from jellyfish._openapi_client.models.component_options_hlss3 import ( + ComponentOptionsHLSS3, +) from jellyfish._openapi_client.models.component_options_rtsp import ComponentOptionsRTSP from jellyfish._openapi_client.models.component_rtsp import ComponentRTSP from jellyfish._openapi_client.models.error import Error @@ -52,6 +56,9 @@ from jellyfish._openapi_client.models.peer_options import PeerOptions from jellyfish._openapi_client.models.peer_options_web_rtc import PeerOptionsWebRTC from jellyfish._openapi_client.models.peer_status import PeerStatus +from jellyfish._openapi_client.models.recording_list_response import ( + RecordingListResponse, +) from jellyfish._openapi_client.models.room import Room from jellyfish._openapi_client.models.room_config import RoomConfig from jellyfish._openapi_client.models.room_create_details_response import ( @@ -62,3 +69,5 @@ ) from jellyfish._openapi_client.models.room_details_response import RoomDetailsResponse from jellyfish._openapi_client.models.rooms_listing_response import RoomsListingResponse +from jellyfish._openapi_client.models.s3_credentials import S3Credentials +from jellyfish._openapi_client.models.subscription_config import SubscriptionConfig diff --git a/jellyfish/_openapi_client/api/__init__.py b/jellyfish/_openapi_client/api/__init__.py index 5820a27..4d0419d 100644 --- a/jellyfish/_openapi_client/api/__init__.py +++ b/jellyfish/_openapi_client/api/__init__.py @@ -1,5 +1,6 @@ # flake8: noqa # import apis into api package -from jellyfish._openapi_client.api.default_api import DefaultApi +from jellyfish._openapi_client.api.hls_api import HlsApi +from jellyfish._openapi_client.api.recording_api import RecordingApi from jellyfish._openapi_client.api.room_api import RoomApi diff --git a/jellyfish/_openapi_client/api/default_api.py b/jellyfish/_openapi_client/api/hls_api.py similarity index 54% rename from jellyfish/_openapi_client/api/default_api.py rename to jellyfish/_openapi_client/api/hls_api.py index 772c03e..db66759 100644 --- a/jellyfish/_openapi_client/api/default_api.py +++ b/jellyfish/_openapi_client/api/hls_api.py @@ -22,6 +22,7 @@ from typing import Optional from jellyfish._openapi_client.models.hls_skip import HlsSkip +from jellyfish._openapi_client.models.subscription_config import SubscriptionConfig from jellyfish._openapi_client.api_client import ApiClient from jellyfish._openapi_client.api_response import ApiResponse @@ -31,7 +32,7 @@ ) -class DefaultApi(object): +class HlsApi(object): """NOTE: This class is auto generated by OpenAPI Generator Ref: https://openapi-generator.tech @@ -44,7 +45,7 @@ def __init__(self, api_client=None): self.api_client = api_client @validate_arguments - def jellyfish_web_hls_controller_index( + def get_hls_content( self, room_id: Annotated[StrictStr, Field(..., description="Room id")], filename: Annotated[StrictStr, Field(..., description="Name of the file")], @@ -64,12 +65,12 @@ def jellyfish_web_hls_controller_index( ] = None, **kwargs ) -> str: # noqa: E501 - """Send file # noqa: E501 + """Retrieve HLS Content # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.jellyfish_web_hls_controller_index(room_id, filename, range, hls_msn, hls_part, hls_skip, async_req=True) + >>> thread = api.get_hls_content(room_id, filename, range, hls_msn, hls_part, hls_skip, async_req=True) >>> result = thread.get() :param room_id: Room id (required) @@ -98,14 +99,14 @@ def jellyfish_web_hls_controller_index( kwargs["_return_http_data_only"] = True if "_preload_content" in kwargs: raise ValueError( - "Error! Please call the jellyfish_web_hls_controller_index_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" + "Error! Please call the get_hls_content_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" ) - return self.jellyfish_web_hls_controller_index_with_http_info( + return self.get_hls_content_with_http_info( room_id, filename, range, hls_msn, hls_part, hls_skip, **kwargs ) # noqa: E501 @validate_arguments - def jellyfish_web_hls_controller_index_with_http_info( + def get_hls_content_with_http_info( self, room_id: Annotated[StrictStr, Field(..., description="Room id")], filename: Annotated[StrictStr, Field(..., description="Name of the file")], @@ -125,12 +126,12 @@ def jellyfish_web_hls_controller_index_with_http_info( ] = None, **kwargs ) -> ApiResponse: # noqa: E501 - """Send file # noqa: E501 + """Retrieve HLS Content # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.jellyfish_web_hls_controller_index_with_http_info(room_id, filename, range, hls_msn, hls_part, hls_skip, async_req=True) + >>> thread = api.get_hls_content_with_http_info(room_id, filename, range, hls_msn, hls_part, hls_skip, async_req=True) >>> result = thread.get() :param room_id: Room id (required) @@ -197,7 +198,7 @@ def jellyfish_web_hls_controller_index_with_http_info( if _key not in _all_params: raise ApiTypeError( "Got an unexpected keyword argument '%s'" - " to method jellyfish_web_hls_controller_index" % _key + " to method get_hls_content" % _key ) _params[_key] = _val del _params["kwargs"] @@ -264,3 +265,171 @@ def jellyfish_web_hls_controller_index_with_http_info( collection_formats=_collection_formats, _request_auth=_params.get("_request_auth"), ) + + @validate_arguments + def subscribe_tracks( + self, + room_id: Annotated[StrictStr, Field(..., description="Room ID")], + subscription_config: Annotated[ + Optional[SubscriptionConfig], Field(description="Subscribe configuration") + ] = None, + **kwargs + ) -> None: # noqa: E501 + """Subscribe hls component for tracks # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.subscribe_tracks(room_id, subscription_config, async_req=True) + >>> result = thread.get() + + :param room_id: Room ID (required) + :type room_id: str + :param subscription_config: Subscribe configuration + :type subscription_config: SubscriptionConfig + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs["_return_http_data_only"] = True + if "_preload_content" in kwargs: + raise ValueError( + "Error! Please call the subscribe_tracks_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" + ) + return self.subscribe_tracks_with_http_info( + room_id, subscription_config, **kwargs + ) # noqa: E501 + + @validate_arguments + def subscribe_tracks_with_http_info( + self, + room_id: Annotated[StrictStr, Field(..., description="Room ID")], + subscription_config: Annotated[ + Optional[SubscriptionConfig], Field(description="Subscribe configuration") + ] = None, + **kwargs + ) -> ApiResponse: # noqa: E501 + """Subscribe hls component for tracks # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.subscribe_tracks_with_http_info(room_id, subscription_config, async_req=True) + >>> result = thread.get() + + :param room_id: Room ID (required) + :type room_id: str + :param subscription_config: Subscribe configuration + :type subscription_config: SubscriptionConfig + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = ["room_id", "subscription_config"] + _all_params.extend( + [ + "async_req", + "_return_http_data_only", + "_preload_content", + "_request_timeout", + "_request_auth", + "_content_type", + "_headers", + ] + ) + + # validate the arguments + for _key, _val in _params["kwargs"].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method subscribe_tracks" % _key + ) + _params[_key] = _val + del _params["kwargs"] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params["room_id"]: + _path_params["room_id"] = _params["room_id"] + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get("_headers", {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + if _params["subscription_config"] is not None: + _body_params = _params["subscription_config"] + + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) # noqa: E501 + + # set the HTTP header `Content-Type` + _content_types_list = _params.get( + "_content_type", + self.api_client.select_header_content_type(["application/json"]), + ) + if _content_types_list: + _header_params["Content-Type"] = _content_types_list + + # authentication setting + _auth_settings = ["authorization"] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + "/hls/{room_id}/subscribe", + "POST", + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get("async_req"), + _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 + _preload_content=_params.get("_preload_content", True), + _request_timeout=_params.get("_request_timeout"), + collection_formats=_collection_formats, + _request_auth=_params.get("_request_auth"), + ) diff --git a/jellyfish/_openapi_client/api/recording_api.py b/jellyfish/_openapi_client/api/recording_api.py new file mode 100644 index 0000000..bfa91a9 --- /dev/null +++ b/jellyfish/_openapi_client/api/recording_api.py @@ -0,0 +1,484 @@ +# coding: utf-8 + +""" + Python API wrapper for Jellyfish Media Server + + The version of the OpenAPI document: 0.2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import re # noqa: F401 +import io +import warnings + +from pydantic import validate_arguments, ValidationError +from typing_extensions import Annotated + +from pydantic import Field, StrictStr + +from jellyfish._openapi_client.models.recording_list_response import ( + RecordingListResponse, +) + +from jellyfish._openapi_client.api_client import ApiClient +from jellyfish._openapi_client.api_response import ApiResponse +from jellyfish._openapi_client.exceptions import ( # noqa: F401 + ApiTypeError, + ApiValueError, +) + + +class RecordingApi(object): + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None): + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + @validate_arguments + def delete_recording( + self, + recording_id: Annotated[StrictStr, Field(..., description="Recording id")], + **kwargs + ) -> None: # noqa: E501 + """Deletes the recording # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.delete_recording(recording_id, async_req=True) + >>> result = thread.get() + + :param recording_id: Recording id (required) + :type recording_id: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs["_return_http_data_only"] = True + if "_preload_content" in kwargs: + raise ValueError( + "Error! Please call the delete_recording_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" + ) + return self.delete_recording_with_http_info( + recording_id, **kwargs + ) # noqa: E501 + + @validate_arguments + def delete_recording_with_http_info( + self, + recording_id: Annotated[StrictStr, Field(..., description="Recording id")], + **kwargs + ) -> ApiResponse: # noqa: E501 + """Deletes the recording # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.delete_recording_with_http_info(recording_id, async_req=True) + >>> result = thread.get() + + :param recording_id: Recording id (required) + :type recording_id: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = ["recording_id"] + _all_params.extend( + [ + "async_req", + "_return_http_data_only", + "_preload_content", + "_request_timeout", + "_request_auth", + "_content_type", + "_headers", + ] + ) + + # validate the arguments + for _key, _val in _params["kwargs"].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method delete_recording" % _key + ) + _params[_key] = _val + del _params["kwargs"] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params["recording_id"]: + _path_params["recording_id"] = _params["recording_id"] + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get("_headers", {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) # noqa: E501 + + # authentication setting + _auth_settings = ["authorization"] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + "/recording/{recording_id}", + "DELETE", + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get("async_req"), + _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 + _preload_content=_params.get("_preload_content", True), + _request_timeout=_params.get("_request_timeout"), + collection_formats=_collection_formats, + _request_auth=_params.get("_request_auth"), + ) + + @validate_arguments + def get_recording_content( + self, + recording_id: Annotated[StrictStr, Field(..., description="Recording id")], + filename: Annotated[StrictStr, Field(..., description="Name of the file")], + **kwargs + ) -> str: # noqa: E501 + """Retrieve Recording (HLS) Content # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_recording_content(recording_id, filename, async_req=True) + >>> result = thread.get() + + :param recording_id: Recording id (required) + :type recording_id: str + :param filename: Name of the file (required) + :type filename: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: str + """ + kwargs["_return_http_data_only"] = True + if "_preload_content" in kwargs: + raise ValueError( + "Error! Please call the get_recording_content_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" + ) + return self.get_recording_content_with_http_info( + recording_id, filename, **kwargs + ) # noqa: E501 + + @validate_arguments + def get_recording_content_with_http_info( + self, + recording_id: Annotated[StrictStr, Field(..., description="Recording id")], + filename: Annotated[StrictStr, Field(..., description="Name of the file")], + **kwargs + ) -> ApiResponse: # noqa: E501 + """Retrieve Recording (HLS) Content # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_recording_content_with_http_info(recording_id, filename, async_req=True) + >>> result = thread.get() + + :param recording_id: Recording id (required) + :type recording_id: str + :param filename: Name of the file (required) + :type filename: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(str, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = ["recording_id", "filename"] + _all_params.extend( + [ + "async_req", + "_return_http_data_only", + "_preload_content", + "_request_timeout", + "_request_auth", + "_content_type", + "_headers", + ] + ) + + # validate the arguments + for _key, _val in _params["kwargs"].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method get_recording_content" % _key + ) + _params[_key] = _val + del _params["kwargs"] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params["recording_id"]: + _path_params["recording_id"] = _params["recording_id"] + + if _params["filename"]: + _path_params["filename"] = _params["filename"] + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get("_headers", {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) # noqa: E501 + + # authentication setting + _auth_settings = ["authorization"] # noqa: E501 + + _response_types_map = { + "200": "str", + "404": "Error", + } + + return self.api_client.call_api( + "/recording/{recording_id}/{filename}", + "GET", + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get("async_req"), + _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 + _preload_content=_params.get("_preload_content", True), + _request_timeout=_params.get("_request_timeout"), + collection_formats=_collection_formats, + _request_auth=_params.get("_request_auth"), + ) + + @validate_arguments + def get_recordings(self, **kwargs) -> RecordingListResponse: # noqa: E501 + """Lists all available recordings # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_recordings(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: RecordingListResponse + """ + kwargs["_return_http_data_only"] = True + if "_preload_content" in kwargs: + raise ValueError( + "Error! Please call the get_recordings_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" + ) + return self.get_recordings_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def get_recordings_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """Lists all available recordings # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_recordings_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(RecordingListResponse, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [] + _all_params.extend( + [ + "async_req", + "_return_http_data_only", + "_preload_content", + "_request_timeout", + "_request_auth", + "_content_type", + "_headers", + ] + ) + + # validate the arguments + for _key, _val in _params["kwargs"].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method get_recordings" % _key + ) + _params[_key] = _val + del _params["kwargs"] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get("_headers", {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) # noqa: E501 + + # authentication setting + _auth_settings = ["authorization"] # noqa: E501 + + _response_types_map = { + "200": "RecordingListResponse", + "404": "Error", + } + + return self.api_client.call_api( + "/recording", + "GET", + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get("async_req"), + _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 + _preload_content=_params.get("_preload_content", True), + _request_timeout=_params.get("_request_timeout"), + collection_formats=_collection_formats, + _request_auth=_params.get("_request_auth"), + ) diff --git a/jellyfish/_openapi_client/models/__init__.py b/jellyfish/_openapi_client/models/__init__.py index a7774d9..dc1acea 100644 --- a/jellyfish/_openapi_client/models/__init__.py +++ b/jellyfish/_openapi_client/models/__init__.py @@ -22,6 +22,9 @@ from jellyfish._openapi_client.models.component_metadata_hls import ComponentMetadataHLS from jellyfish._openapi_client.models.component_options import ComponentOptions from jellyfish._openapi_client.models.component_options_hls import ComponentOptionsHLS +from jellyfish._openapi_client.models.component_options_hlss3 import ( + ComponentOptionsHLSS3, +) from jellyfish._openapi_client.models.component_options_rtsp import ComponentOptionsRTSP from jellyfish._openapi_client.models.component_rtsp import ComponentRTSP from jellyfish._openapi_client.models.error import Error @@ -34,6 +37,9 @@ from jellyfish._openapi_client.models.peer_options import PeerOptions from jellyfish._openapi_client.models.peer_options_web_rtc import PeerOptionsWebRTC from jellyfish._openapi_client.models.peer_status import PeerStatus +from jellyfish._openapi_client.models.recording_list_response import ( + RecordingListResponse, +) from jellyfish._openapi_client.models.room import Room from jellyfish._openapi_client.models.room_config import RoomConfig from jellyfish._openapi_client.models.room_create_details_response import ( @@ -44,3 +50,5 @@ ) from jellyfish._openapi_client.models.room_details_response import RoomDetailsResponse from jellyfish._openapi_client.models.rooms_listing_response import RoomsListingResponse +from jellyfish._openapi_client.models.s3_credentials import S3Credentials +from jellyfish._openapi_client.models.subscription_config import SubscriptionConfig diff --git a/jellyfish/_openapi_client/models/component_metadata_hls.py b/jellyfish/_openapi_client/models/component_metadata_hls.py index 6ecdbe5..68f0936 100644 --- a/jellyfish/_openapi_client/models/component_metadata_hls.py +++ b/jellyfish/_openapi_client/models/component_metadata_hls.py @@ -17,7 +17,7 @@ from typing import Optional -from pydantic import BaseModel, Field, StrictBool, StrictInt +from pydantic import BaseModel, Field, StrictBool, StrictInt, StrictStr, validator class ComponentMetadataHLS(BaseModel): @@ -34,12 +34,30 @@ class ComponentMetadataHLS(BaseModel): playable: StrictBool = Field( ..., description="Whether the generated HLS playlist is playable" ) + subscribe_mode: StrictStr = Field( + ..., + alias="subscribeMode", + description="Whether the HLS component should subscribe to tracks automatically or manually", + ) target_window_duration: Optional[StrictInt] = Field( ..., alias="targetWindowDuration", description="Duration of stream available for viewer", ) - __properties = ["lowLatency", "persistent", "playable", "targetWindowDuration"] + __properties = [ + "lowLatency", + "persistent", + "playable", + "subscribeMode", + "targetWindowDuration", + ] + + @validator("subscribe_mode") + def subscribe_mode_validate_enum(cls, value): + """Validates the enum""" + if value not in ("auto", "manual"): + raise ValueError("must be one of enum values ('auto', 'manual')") + return value class Config: """Pydantic configuration""" @@ -87,6 +105,7 @@ def from_dict(cls, obj: dict) -> ComponentMetadataHLS: "low_latency": obj.get("lowLatency"), "persistent": obj.get("persistent"), "playable": obj.get("playable"), + "subscribe_mode": obj.get("subscribeMode"), "target_window_duration": obj.get("targetWindowDuration"), } ) diff --git a/jellyfish/_openapi_client/models/component_options_hls.py b/jellyfish/_openapi_client/models/component_options_hls.py index 102b891..3f31589 100644 --- a/jellyfish/_openapi_client/models/component_options_hls.py +++ b/jellyfish/_openapi_client/models/component_options_hls.py @@ -17,7 +17,10 @@ from typing import Optional -from pydantic import BaseModel, Field, StrictBool, StrictInt +from pydantic import BaseModel, Field, StrictBool, StrictInt, StrictStr, validator +from jellyfish._openapi_client.models.component_options_hlss3 import ( + ComponentOptionsHLSS3, +) class ComponentOptionsHLS(BaseModel): @@ -31,12 +34,34 @@ class ComponentOptionsHLS(BaseModel): persistent: Optional[StrictBool] = Field( False, description="Whether the video is stored after end of stream" ) + s3: Optional[ComponentOptionsHLSS3] = None + subscribe_mode: Optional[StrictStr] = Field( + "auto", + alias="subscribeMode", + description="Whether the HLS component should subscribe to tracks automatically or manually.", + ) target_window_duration: Optional[StrictInt] = Field( None, alias="targetWindowDuration", description="Duration of stream available for viewer", ) - __properties = ["lowLatency", "persistent", "targetWindowDuration"] + __properties = [ + "lowLatency", + "persistent", + "s3", + "subscribeMode", + "targetWindowDuration", + ] + + @validator("subscribe_mode") + def subscribe_mode_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in ("auto", "manual"): + raise ValueError("must be one of enum values ('auto', 'manual')") + return value class Config: """Pydantic configuration""" @@ -60,6 +85,14 @@ def from_json(cls, json_str: str) -> ComponentOptionsHLS: def to_dict(self): """Returns the dictionary representation of the model using alias""" _dict = self.dict(by_alias=True, exclude={}, exclude_none=True) + # override the default output from pydantic by calling `to_dict()` of s3 + if self.s3: + _dict["s3"] = self.s3.to_dict() + # set to None if s3 (nullable) is None + # and __fields_set__ contains the field + if self.s3 is None and "s3" in self.__fields_set__: + _dict["s3"] = None + # set to None if target_window_duration (nullable) is None # and __fields_set__ contains the field if ( @@ -87,6 +120,12 @@ def from_dict(cls, obj: dict) -> ComponentOptionsHLS: "persistent": obj.get("persistent") if obj.get("persistent") is not None else False, + "s3": ComponentOptionsHLSS3.from_dict(obj.get("s3")) + if obj.get("s3") is not None + else None, + "subscribe_mode": obj.get("subscribeMode") + if obj.get("subscribeMode") is not None + else "auto", "target_window_duration": obj.get("targetWindowDuration"), } ) diff --git a/jellyfish/_openapi_client/models/component_options_hlss3.py b/jellyfish/_openapi_client/models/component_options_hlss3.py new file mode 100644 index 0000000..cb146dd --- /dev/null +++ b/jellyfish/_openapi_client/models/component_options_hlss3.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" + Python API wrapper for Jellyfish Media Server + + The version of the OpenAPI document: 0.2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 + +from typing import Any, List, Optional +from pydantic import BaseModel, Field, StrictStr, ValidationError, validator +from jellyfish._openapi_client.models.s3_credentials import S3Credentials +from typing import Union, Any, List, TYPE_CHECKING +from pydantic import StrictStr, Field + +COMPONENTOPTIONSHLSS3_ONE_OF_SCHEMAS = ["S3Credentials"] + + +class ComponentOptionsHLSS3(BaseModel): + """ + Credentials to AWS S3 bucket. + """ + + # data type: S3Credentials + oneof_schema_1_validator: Optional[S3Credentials] = None + if TYPE_CHECKING: + actual_instance: Union[S3Credentials] + else: + actual_instance: Any + one_of_schemas: List[str] = Field(COMPONENTOPTIONSHLSS3_ONE_OF_SCHEMAS, const=True) + + class Config: + validate_assignment = True + + def __init__(self, *args, **kwargs): + if args: + if len(args) > 1: + raise ValueError( + "If a position argument is used, only 1 is allowed to set `actual_instance`" + ) + if kwargs: + raise ValueError( + "If a position argument is used, keyword arguments cannot be used." + ) + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @validator("actual_instance") + def actual_instance_must_validate_oneof(cls, v): + if v is None: + return v + + instance = ComponentOptionsHLSS3.construct() + error_messages = [] + match = 0 + # validate data type: S3Credentials + if not isinstance(v, S3Credentials): + error_messages.append( + f"Error! Input type `{type(v)}` is not `S3Credentials`" + ) + else: + match += 1 + if match > 1: + # more than 1 match + raise ValueError( + "Multiple matches found when setting `actual_instance` in ComponentOptionsHLSS3 with oneOf schemas: S3Credentials. Details: " + + ", ".join(error_messages) + ) + elif match == 0: + # no match + raise ValueError( + "No match found when setting `actual_instance` in ComponentOptionsHLSS3 with oneOf schemas: S3Credentials. Details: " + + ", ".join(error_messages) + ) + else: + return v + + @classmethod + def from_dict(cls, obj: dict) -> ComponentOptionsHLSS3: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> ComponentOptionsHLSS3: + """Returns the object represented by the json string""" + instance = ComponentOptionsHLSS3.construct() + if json_str is None: + return instance + + error_messages = [] + match = 0 + + # deserialize data into S3Credentials + try: + instance.actual_instance = S3Credentials.from_json(json_str) + match += 1 + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if match > 1: + # more than 1 match + raise ValueError( + "Multiple matches found when deserializing the JSON string into ComponentOptionsHLSS3 with oneOf schemas: S3Credentials. Details: " + + ", ".join(error_messages) + ) + elif match == 0: + # no match + raise ValueError( + "No match found when deserializing the JSON string into ComponentOptionsHLSS3 with oneOf schemas: S3Credentials. Details: " + + ", ".join(error_messages) + ) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + to_json = getattr(self.actual_instance, "to_json", None) + if callable(to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> dict: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + to_dict = getattr(self.actual_instance, "to_dict", None) + if callable(to_dict): + return self.actual_instance.to_dict() + else: + # primitive type + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.dict()) diff --git a/jellyfish/_openapi_client/models/recording_list_response.py b/jellyfish/_openapi_client/models/recording_list_response.py new file mode 100644 index 0000000..1378b7e --- /dev/null +++ b/jellyfish/_openapi_client/models/recording_list_response.py @@ -0,0 +1,65 @@ +# coding: utf-8 + +""" + Python API wrapper for Jellyfish Media Server + + The version of the OpenAPI document: 0.2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import List +from pydantic import BaseModel, Field, StrictStr, conlist + + +class RecordingListResponse(BaseModel): + """ + Response containing list of all recording + """ + + data: conlist(StrictStr) = Field(...) + __properties = ["data"] + + class Config: + """Pydantic configuration""" + + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> RecordingListResponse: + """Create an instance of RecordingListResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, exclude={}, exclude_none=True) + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> RecordingListResponse: + """Create an instance of RecordingListResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return RecordingListResponse.parse_obj(obj) + + _obj = RecordingListResponse.parse_obj({"data": obj.get("data")}) + return _obj diff --git a/jellyfish/_openapi_client/models/s3_credentials.py b/jellyfish/_openapi_client/models/s3_credentials.py new file mode 100644 index 0000000..55ff77a --- /dev/null +++ b/jellyfish/_openapi_client/models/s3_credentials.py @@ -0,0 +1,86 @@ +# coding: utf-8 + +""" + Python API wrapper for Jellyfish Media Server + + The version of the OpenAPI document: 0.2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from pydantic import BaseModel, Field, StrictStr + + +class S3Credentials(BaseModel): + """ + An AWS S3 credential that will be used to send HLS stream. The stream will only be uploaded if credentials are provided + """ + + access_key_id: StrictStr = Field( + ..., + alias="accessKeyId", + description="An AWS access key identifier, linked to your AWS account.", + ) + bucket: StrictStr = Field( + ..., description="The name of the S3 bucket where your data will be stored." + ) + region: StrictStr = Field( + ..., description="The AWS region where your bucket is located." + ) + secret_access_key: StrictStr = Field( + ..., + alias="secretAccessKey", + description="The secret key that is linked to the Access Key ID.", + ) + __properties = ["accessKeyId", "bucket", "region", "secretAccessKey"] + + class Config: + """Pydantic configuration""" + + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> S3Credentials: + """Create an instance of S3Credentials from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, exclude={}, exclude_none=True) + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> S3Credentials: + """Create an instance of S3Credentials from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return S3Credentials.parse_obj(obj) + + _obj = S3Credentials.parse_obj( + { + "access_key_id": obj.get("accessKeyId"), + "bucket": obj.get("bucket"), + "region": obj.get("region"), + "secret_access_key": obj.get("secretAccessKey"), + } + ) + return _obj diff --git a/jellyfish/_openapi_client/models/subscription_config.py b/jellyfish/_openapi_client/models/subscription_config.py new file mode 100644 index 0000000..8c2fe76 --- /dev/null +++ b/jellyfish/_openapi_client/models/subscription_config.py @@ -0,0 +1,67 @@ +# coding: utf-8 + +""" + Python API wrapper for Jellyfish Media Server + + The version of the OpenAPI document: 0.2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import List, Optional +from pydantic import BaseModel, Field, StrictStr, conlist + + +class SubscriptionConfig(BaseModel): + """ + Subscription config + """ + + tracks: Optional[conlist(StrictStr)] = Field( + None, description="List of tracks that hls endpoint will subscribe for" + ) + __properties = ["tracks"] + + class Config: + """Pydantic configuration""" + + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> SubscriptionConfig: + """Create an instance of SubscriptionConfig from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, exclude={}, exclude_none=True) + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> SubscriptionConfig: + """Create an instance of SubscriptionConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return SubscriptionConfig.parse_obj(obj) + + _obj = SubscriptionConfig.parse_obj({"tracks": obj.get("tracks")}) + return _obj diff --git a/jellyfish/_room_api.py b/jellyfish/_room_api.py index 5957c18..81691bd 100644 --- a/jellyfish/_room_api.py +++ b/jellyfish/_room_api.py @@ -42,6 +42,7 @@ def __init__( self._api_client = jellyfish_api.ApiClient(self._configuration) self._room_api = jellyfish_api.RoomApi(self._api_client) + self._hls_api = jellyfish_api.HlsApi(self._api_client) def create_room( self, @@ -126,3 +127,8 @@ def delete_component(self, room_id: str, component_id: str) -> None: """Deletes component""" return self._room_api.delete_component(room_id, component_id) + + def hls_subscribe(self, room_id: str, tracks: list): + """subscribes hls component for tracks""" + + return self._hls_api.subscribe_tracks(room_id, {"tracks": tracks}) diff --git a/tests/test_room_api.py b/tests/test_room_api.py index fda6b3f..14142d0 100644 --- a/tests/test_room_api.py +++ b/tests/test_room_api.py @@ -11,7 +11,7 @@ from jellyfish import ValidationError -from jellyfish import UnauthorizedException, NotFoundException +from jellyfish import UnauthorizedException, NotFoundException, BadRequestException HOST = "jellyfish" if os.getenv("DOCKER_TEST") == "TRUE" else "localhost" @@ -173,6 +173,21 @@ def test_invalid_component(self, room_api: RoomApi): room_api.delete_component(room.id, "invalid_id") +class TestHLSSubscribe: + def test_valid_subscription(self, room_api: RoomApi): + _, room = room_api.create_room(video_codec=CODEC_H264) + _ = room_api.add_component( + room.id, options=ComponentOptionsHLS(subscribe_mode="manual") + ) + assert room_api.hls_subscribe(room.id, ["track-id"]) is None + + def test_invalid_subscription(self, room_api: RoomApi): + _, room = room_api.create_room(video_codec=CODEC_H264) + _ = room_api.add_component(room.id, options=HLS_OPTIONS) + with pytest.raises(BadRequestException): + room_api.hls_subscribe(room.id, ["track-id"]) + + class TestAddPeer: def _assert_peer_created(self, room_api, peer, room_id): assert peer.status == "disconnected" From ef6241cd0d08380dd058caea6aff2d31212677df Mon Sep 17 00:00:00 2001 From: Karol Konkol Date: Thu, 30 Nov 2023 16:57:46 +0100 Subject: [PATCH 2/2] Remove recording api --- jellyfish/_openapi_client/__init__.py | 4 - jellyfish/_openapi_client/api/__init__.py | 1 - .../_openapi_client/api/recording_api.py | 484 ------------------ jellyfish/_openapi_client/models/__init__.py | 3 - .../models/recording_list_response.py | 65 --- 5 files changed, 557 deletions(-) delete mode 100644 jellyfish/_openapi_client/api/recording_api.py delete mode 100644 jellyfish/_openapi_client/models/recording_list_response.py diff --git a/jellyfish/_openapi_client/__init__.py b/jellyfish/_openapi_client/__init__.py index 34855c8..f450a36 100644 --- a/jellyfish/_openapi_client/__init__.py +++ b/jellyfish/_openapi_client/__init__.py @@ -16,7 +16,6 @@ # import apis into sdk package from jellyfish._openapi_client.api.hls_api import HlsApi -from jellyfish._openapi_client.api.recording_api import RecordingApi from jellyfish._openapi_client.api.room_api import RoomApi # import ApiClient @@ -56,9 +55,6 @@ from jellyfish._openapi_client.models.peer_options import PeerOptions from jellyfish._openapi_client.models.peer_options_web_rtc import PeerOptionsWebRTC from jellyfish._openapi_client.models.peer_status import PeerStatus -from jellyfish._openapi_client.models.recording_list_response import ( - RecordingListResponse, -) from jellyfish._openapi_client.models.room import Room from jellyfish._openapi_client.models.room_config import RoomConfig from jellyfish._openapi_client.models.room_create_details_response import ( diff --git a/jellyfish/_openapi_client/api/__init__.py b/jellyfish/_openapi_client/api/__init__.py index 4d0419d..480f08c 100644 --- a/jellyfish/_openapi_client/api/__init__.py +++ b/jellyfish/_openapi_client/api/__init__.py @@ -2,5 +2,4 @@ # import apis into api package from jellyfish._openapi_client.api.hls_api import HlsApi -from jellyfish._openapi_client.api.recording_api import RecordingApi from jellyfish._openapi_client.api.room_api import RoomApi diff --git a/jellyfish/_openapi_client/api/recording_api.py b/jellyfish/_openapi_client/api/recording_api.py deleted file mode 100644 index bfa91a9..0000000 --- a/jellyfish/_openapi_client/api/recording_api.py +++ /dev/null @@ -1,484 +0,0 @@ -# coding: utf-8 - -""" - Python API wrapper for Jellyfish Media Server - - The version of the OpenAPI document: 0.2.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import re # noqa: F401 -import io -import warnings - -from pydantic import validate_arguments, ValidationError -from typing_extensions import Annotated - -from pydantic import Field, StrictStr - -from jellyfish._openapi_client.models.recording_list_response import ( - RecordingListResponse, -) - -from jellyfish._openapi_client.api_client import ApiClient -from jellyfish._openapi_client.api_response import ApiResponse -from jellyfish._openapi_client.exceptions import ( # noqa: F401 - ApiTypeError, - ApiValueError, -) - - -class RecordingApi(object): - """NOTE: This class is auto generated by OpenAPI Generator - Ref: https://openapi-generator.tech - - Do not edit the class manually. - """ - - def __init__(self, api_client=None): - if api_client is None: - api_client = ApiClient.get_default() - self.api_client = api_client - - @validate_arguments - def delete_recording( - self, - recording_id: Annotated[StrictStr, Field(..., description="Recording id")], - **kwargs - ) -> None: # noqa: E501 - """Deletes the recording # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.delete_recording(recording_id, async_req=True) - >>> result = thread.get() - - :param recording_id: Recording id (required) - :type recording_id: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - kwargs["_return_http_data_only"] = True - if "_preload_content" in kwargs: - raise ValueError( - "Error! Please call the delete_recording_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" - ) - return self.delete_recording_with_http_info( - recording_id, **kwargs - ) # noqa: E501 - - @validate_arguments - def delete_recording_with_http_info( - self, - recording_id: Annotated[StrictStr, Field(..., description="Recording id")], - **kwargs - ) -> ApiResponse: # noqa: E501 - """Deletes the recording # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.delete_recording_with_http_info(recording_id, async_req=True) - >>> result = thread.get() - - :param recording_id: Recording id (required) - :type recording_id: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - - _params = locals() - - _all_params = ["recording_id"] - _all_params.extend( - [ - "async_req", - "_return_http_data_only", - "_preload_content", - "_request_timeout", - "_request_auth", - "_content_type", - "_headers", - ] - ) - - # validate the arguments - for _key, _val in _params["kwargs"].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method delete_recording" % _key - ) - _params[_key] = _val - del _params["kwargs"] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - if _params["recording_id"]: - _path_params["recording_id"] = _params["recording_id"] - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get("_headers", {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - # set the HTTP header `Accept` - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] - ) # noqa: E501 - - # authentication setting - _auth_settings = ["authorization"] # noqa: E501 - - _response_types_map = {} - - return self.api_client.call_api( - "/recording/{recording_id}", - "DELETE", - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get("async_req"), - _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 - _preload_content=_params.get("_preload_content", True), - _request_timeout=_params.get("_request_timeout"), - collection_formats=_collection_formats, - _request_auth=_params.get("_request_auth"), - ) - - @validate_arguments - def get_recording_content( - self, - recording_id: Annotated[StrictStr, Field(..., description="Recording id")], - filename: Annotated[StrictStr, Field(..., description="Name of the file")], - **kwargs - ) -> str: # noqa: E501 - """Retrieve Recording (HLS) Content # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.get_recording_content(recording_id, filename, async_req=True) - >>> result = thread.get() - - :param recording_id: Recording id (required) - :type recording_id: str - :param filename: Name of the file (required) - :type filename: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: str - """ - kwargs["_return_http_data_only"] = True - if "_preload_content" in kwargs: - raise ValueError( - "Error! Please call the get_recording_content_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" - ) - return self.get_recording_content_with_http_info( - recording_id, filename, **kwargs - ) # noqa: E501 - - @validate_arguments - def get_recording_content_with_http_info( - self, - recording_id: Annotated[StrictStr, Field(..., description="Recording id")], - filename: Annotated[StrictStr, Field(..., description="Name of the file")], - **kwargs - ) -> ApiResponse: # noqa: E501 - """Retrieve Recording (HLS) Content # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.get_recording_content_with_http_info(recording_id, filename, async_req=True) - >>> result = thread.get() - - :param recording_id: Recording id (required) - :type recording_id: str - :param filename: Name of the file (required) - :type filename: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: tuple(str, status_code(int), headers(HTTPHeaderDict)) - """ - - _params = locals() - - _all_params = ["recording_id", "filename"] - _all_params.extend( - [ - "async_req", - "_return_http_data_only", - "_preload_content", - "_request_timeout", - "_request_auth", - "_content_type", - "_headers", - ] - ) - - # validate the arguments - for _key, _val in _params["kwargs"].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method get_recording_content" % _key - ) - _params[_key] = _val - del _params["kwargs"] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - if _params["recording_id"]: - _path_params["recording_id"] = _params["recording_id"] - - if _params["filename"]: - _path_params["filename"] = _params["filename"] - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get("_headers", {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - # set the HTTP header `Accept` - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] - ) # noqa: E501 - - # authentication setting - _auth_settings = ["authorization"] # noqa: E501 - - _response_types_map = { - "200": "str", - "404": "Error", - } - - return self.api_client.call_api( - "/recording/{recording_id}/{filename}", - "GET", - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get("async_req"), - _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 - _preload_content=_params.get("_preload_content", True), - _request_timeout=_params.get("_request_timeout"), - collection_formats=_collection_formats, - _request_auth=_params.get("_request_auth"), - ) - - @validate_arguments - def get_recordings(self, **kwargs) -> RecordingListResponse: # noqa: E501 - """Lists all available recordings # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.get_recordings(async_req=True) - >>> result = thread.get() - - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: RecordingListResponse - """ - kwargs["_return_http_data_only"] = True - if "_preload_content" in kwargs: - raise ValueError( - "Error! Please call the get_recordings_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" - ) - return self.get_recordings_with_http_info(**kwargs) # noqa: E501 - - @validate_arguments - def get_recordings_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 - """Lists all available recordings # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.get_recordings_with_http_info(async_req=True) - >>> result = thread.get() - - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: tuple(RecordingListResponse, status_code(int), headers(HTTPHeaderDict)) - """ - - _params = locals() - - _all_params = [] - _all_params.extend( - [ - "async_req", - "_return_http_data_only", - "_preload_content", - "_request_timeout", - "_request_auth", - "_content_type", - "_headers", - ] - ) - - # validate the arguments - for _key, _val in _params["kwargs"].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method get_recordings" % _key - ) - _params[_key] = _val - del _params["kwargs"] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get("_headers", {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - # set the HTTP header `Accept` - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] - ) # noqa: E501 - - # authentication setting - _auth_settings = ["authorization"] # noqa: E501 - - _response_types_map = { - "200": "RecordingListResponse", - "404": "Error", - } - - return self.api_client.call_api( - "/recording", - "GET", - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get("async_req"), - _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501 - _preload_content=_params.get("_preload_content", True), - _request_timeout=_params.get("_request_timeout"), - collection_formats=_collection_formats, - _request_auth=_params.get("_request_auth"), - ) diff --git a/jellyfish/_openapi_client/models/__init__.py b/jellyfish/_openapi_client/models/__init__.py index dc1acea..91a7a66 100644 --- a/jellyfish/_openapi_client/models/__init__.py +++ b/jellyfish/_openapi_client/models/__init__.py @@ -37,9 +37,6 @@ from jellyfish._openapi_client.models.peer_options import PeerOptions from jellyfish._openapi_client.models.peer_options_web_rtc import PeerOptionsWebRTC from jellyfish._openapi_client.models.peer_status import PeerStatus -from jellyfish._openapi_client.models.recording_list_response import ( - RecordingListResponse, -) from jellyfish._openapi_client.models.room import Room from jellyfish._openapi_client.models.room_config import RoomConfig from jellyfish._openapi_client.models.room_create_details_response import ( diff --git a/jellyfish/_openapi_client/models/recording_list_response.py b/jellyfish/_openapi_client/models/recording_list_response.py deleted file mode 100644 index 1378b7e..0000000 --- a/jellyfish/_openapi_client/models/recording_list_response.py +++ /dev/null @@ -1,65 +0,0 @@ -# coding: utf-8 - -""" - Python API wrapper for Jellyfish Media Server - - The version of the OpenAPI document: 0.2.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - - -from typing import List -from pydantic import BaseModel, Field, StrictStr, conlist - - -class RecordingListResponse(BaseModel): - """ - Response containing list of all recording - """ - - data: conlist(StrictStr) = Field(...) - __properties = ["data"] - - class Config: - """Pydantic configuration""" - - allow_population_by_field_name = True - validate_assignment = True - - def to_str(self) -> str: - """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) - - def to_json(self) -> str: - """Returns the JSON representation of the model using alias""" - return json.dumps(self.to_dict()) - - @classmethod - def from_json(cls, json_str: str) -> RecordingListResponse: - """Create an instance of RecordingListResponse from a JSON string""" - return cls.from_dict(json.loads(json_str)) - - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, exclude={}, exclude_none=True) - return _dict - - @classmethod - def from_dict(cls, obj: dict) -> RecordingListResponse: - """Create an instance of RecordingListResponse from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return RecordingListResponse.parse_obj(obj) - - _obj = RecordingListResponse.parse_obj({"data": obj.get("data")}) - return _obj