diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 738ed56..d4106da 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.6.0 +current_version = 3.6.1 commit = True tag = False diff --git a/CHANGES.md b/CHANGES.md index ad36cdf..863b716 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +# Release v3.6.1 +- Fixed broken `opentok.Client.add_archive_stream`, `opentok.Client.remove_archive_stream`, `opentok.Client.add_broadcast_stream` and `opentok.Client.remove_broadcast_stream` methods and tests +- Fixed `opentok.Endpoints.get_archive_stream` and `opentok.Endpoints.get_broadcast_stream` methods + # Release v3.6.0 - Added auto-archive improvements to the `opentok.Client.create_session` method to customize automatically created archives: diff --git a/opentok/endpoints.py b/opentok/endpoints.py index ddbb497..ab5bfa5 100644 --- a/opentok/endpoints.py +++ b/opentok/endpoints.py @@ -7,7 +7,6 @@ class Endpoints(object): Class that provides the endpoint urls """ - def __init__(self, api_url, api_key): self.api_url = api_url self.api_key = api_key @@ -57,7 +56,7 @@ def signaling_url(self, session_id, connection_id=None): return self.get_signaling_url(session_id, connection_id) def get_stream_url(self, session_id, stream_id=None): - """ this method returns the url to get streams information """ + """this method returns the url to get streams information""" url = ( self.api_url + "/v2/project/" @@ -79,7 +78,7 @@ def broadcast_url(self, broadcast_id=None, stop=False, layout=False): return self.get_broadcast_url(broadcast_id, stop, layout) def force_disconnect_url(self, session_id, connection_id): - """ this method returns the force disconnect url endpoint """ + """this method returns the force disconnect url endpoint""" url = ( self.api_url + "/v2/project/" @@ -92,7 +91,7 @@ def force_disconnect_url(self, session_id, connection_id): return url def set_archive_layout_url(self, archive_id): - """ this method returns the url to set the archive layout """ + """this method returns the url to set the archive layout""" url = ( self.api_url + "/v2/project/" @@ -104,12 +103,12 @@ def set_archive_layout_url(self, archive_id): return url def dial_url(self): - """ this method returns the url to initialize a SIP call """ + """this method returns the url to initialize a SIP call""" url = self.api_url + "/v2/project/" + self.api_key + "/dial" return url def set_stream_class_lists_url(self, session_id): - """ this method returns the url to set the stream class list """ + """this method returns the url to set the stream class list""" url = ( self.api_url + "/v2/project/" @@ -121,7 +120,7 @@ def set_stream_class_lists_url(self, session_id): return url def get_broadcast_url(self, broadcast_id=None, stop=False, layout=False): - """ this method returns urls for working with broadcast """ + """this method returns urls for working with broadcast""" url = self.api_url + "/v2/project/" + self.api_key + "/broadcast" if broadcast_id: @@ -130,28 +129,27 @@ def get_broadcast_url(self, broadcast_id=None, stop=False, layout=False): url = url + "/stop" if layout: url = url + "/layout" - + return url def get_mute_all_url(self, session_id): - """ this method returns the urls for muting every stream in a session """ + """this method returns the urls for muting every stream in a session""" url = ( - self.api_url - + "/v2/project/" + self.api_url + + "/v2/project/" + self.api_key + "/session/" + session_id + "/mute" - ) return url def get_dtmf_all_url(self, session_id): - """ this method returns the url for Play DTMF to all clients in the session """ + """this method returns the url for Play DTMF to all clients in the session""" url = ( self.api_url - + "/v2/project/" + + "/v2/project/" + self.api_key + "/session/" + session_id @@ -161,7 +159,7 @@ def get_dtmf_all_url(self, session_id): return url def get_dtmf_specific_url(self, session_id, connection_id): - """ this method returns the url for Play DTMF to a specific client connection""" + """this method returns the url for Play DTMF to a specific client connection""" url = ( self.api_url + "/v2/project/" @@ -176,12 +174,12 @@ def get_dtmf_specific_url(self, session_id, connection_id): return url def get_archive_stream(self, archive_id=None): - """ this method returns urls for working with streamModes in archives """ + """this method returns urls for working with streamModes in archives""" url = ( self.api_url + "/v2/project/" + self.api_key - + "archive/" + + "/archive/" + archive_id + "/streams" ) @@ -189,12 +187,12 @@ def get_archive_stream(self, archive_id=None): return url def get_broadcast_stream(self, broadcast_id=None): - """ this method returns urls for working with streamModes in broadcasts """ + """this method returns urls for working with streamModes in broadcasts""" url = ( self.api_url - + "/v2/partner/" + + "/v2/project/" + self.api_key - + "broadcast/" + + "/broadcast/" + broadcast_id + "/streams" ) @@ -202,7 +200,7 @@ def get_broadcast_stream(self, broadcast_id=None): return url def get_render_url(self, render_id: str = None): - "Returns URLs for working with the Render API.""" + "Returns URLs for working with the Render API." "" url = self.api_url + "/v2/project/" + self.api_key + "/render" if render_id: url += "/" + render_id @@ -212,5 +210,5 @@ def get_render_url(self, render_id: str = None): def get_audio_connector_url(self): """Returns URLs for working with the Audio Connector API.""" url = self.api_url + "/v2/project/" + self.api_key + "/connect" - + return url diff --git a/opentok/opentok.py b/opentok/opentok.py index 4f6e8d6..fec4fbd 100644 --- a/opentok/opentok.py +++ b/opentok/opentok.py @@ -864,28 +864,29 @@ def add_archive_stream( ) if response: - return Archive(self, response.json()) - elif response.status_code == 403: - raise AuthError() - elif response.status_code == 400: - """ - The HTTP response has a 400 status code in the following cases: - You do not pass in a session ID or you pass in an invalid session ID. - No clients are actively connected to the OpenTok session. - You specify an invalid resolution value. - The outputMode property is set to "individual" and you set the resolution property and (which is not supported in individual stream archives). - """ - raise RequestError(response.json().get("message")) - elif response.status_code == 404: - raise NotFoundError("Archive or Stream not found") - elif response.status_code == 405: - raise ArchiveStreamModeError( - "Your archive is configured with a streamMode that does not support stream manipulation." - ) - elif response.status_code == 409: - raise ArchiveError(response.json().get("message")) + if response.status_code == 204: + return None + elif response.status_code == 403: + raise AuthError() + elif response.status_code == 400: + """ + The HTTP response has a 400 status code in the following cases: + You do not pass in a session ID or you pass in an invalid session ID. + No clients are actively connected to the OpenTok session. + You specify an invalid resolution value. + The outputMode property is set to "individual" and you set the resolution property and (which is not supported in individual stream archives). + """ + raise RequestError(response.json().get("message")) + elif response.status_code == 404: + raise NotFoundError("Archive or Stream not found") + elif response.status_code == 405: + raise ArchiveStreamModeError( + "Your archive is configured with a streamMode that does not support stream manipulation." + ) + elif response.status_code == 409: + raise ArchiveError(response.json().get("message")) else: - raise RequestError("An unexpected error occurred", response.status_code) + raise RequestError("An unexpected error occurred.", response.status_code) def remove_archive_stream( self, archive_id: str, stream_id: str @@ -910,28 +911,29 @@ def remove_archive_stream( ) if response: - return Archive(self, response.json()) - elif response.status_code == 403: - raise AuthError() - elif response.status_code == 400: - """ - The HTTP response has a 400 status code in the following cases: - You do not pass in a session ID or you pass in an invalid session ID. - No clients are actively connected to the OpenTok session. - You specify an invalid resolution value. - The outputMode property is set to "individual" and you set the resolution property and (which is not supported in individual stream archives). - """ - raise RequestError(response.json().get("message")) - elif response.status_code == 404: - raise NotFoundError("Archive or Stream not found") - elif response.status_code == 405: - raise ArchiveStreamModeError( - "Your archive is configured with a streamMode that does not support stream manipulation." - ) - elif response.status_code == 409: - raise ArchiveError(response.json().get("message")) + if response.status_code == 204: + return None + elif response.status_code == 403: + raise AuthError() + elif response.status_code == 400: + """ + The HTTP response has a 400 status code in the following cases: + You do not pass in a session ID or you pass in an invalid session ID. + No clients are actively connected to the OpenTok session. + You specify an invalid resolution value. + The outputMode property is set to "individual" and you set the resolution property and (which is not supported in individual stream archives). + """ + raise RequestError(response.json().get("message")) + elif response.status_code == 404: + raise NotFoundError("Archive or Stream not found") + elif response.status_code == 405: + raise ArchiveStreamModeError( + "Your archive is configured with a streamMode that does not support stream manipulation." + ) + elif response.status_code == 409: + raise ArchiveError(response.json().get("message")) else: - raise RequestError("An unexpected error occurred", response.status_code) + raise RequestError("An unexpected error occurred.", response.status_code) def send_signal(self, session_id, payload, connection_id=None): """ @@ -964,26 +966,27 @@ def send_signal(self, session_id, payload, connection_id=None): timeout=self.timeout, ) - if response.status_code == 204: - pass - elif response.status_code == 400: - raise SignalingError( - "One of the signal properties - data, type, sessionId or connectionId - is invalid." - ) - elif response.status_code == 403: - raise AuthError( - "You are not authorized to send the signal. Check your authentication credentials." - ) - elif response.status_code == 404: - raise SignalingError( - "The client specified by the connectionId property is not connected to the session." - ) - elif response.status_code == 413: - raise SignalingError( - "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)." - ) + if response: + if response.status_code == 204: + return None + elif response.status_code == 400: + raise SignalingError( + "One of the signal properties - data, type, sessionId or connectionId - is invalid." + ) + elif response.status_code == 403: + raise AuthError( + "You are not authorized to send the signal. Check your authentication credentials." + ) + elif response.status_code == 404: + raise SignalingError( + "The client specified by the connectionId property is not connected to the session." + ) + elif response.status_code == 413: + raise SignalingError( + "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)." + ) else: - raise RequestError("An unexpected error occurred", response.status_code) + raise RequestError("An unexpected error occurred.", response.status_code) def signal(self, session_id, payload, connection_id=None): warnings.warn( @@ -1559,24 +1562,25 @@ def add_broadcast_stream( ) if response: - return Broadcast(response.json()) - elif response.status_code == 400: - raise BroadcastError( - "Invalid request. This response may indicate that data in your request data is " - "invalid JSON. It may also indicate that you passed in invalid layout options. " - "Or you have exceeded the limit of five simultaneous RTMP streams for an OpenTok " - "session. Or you specified and invalid resolution." - ) - elif response.status_code == 403: - raise AuthError("Authentication error.") - elif response.status_code == 405: - raise BroadcastStreamModeError( - "Your broadcast is configured with a streamMode that does not support stream manipulation." - ) - elif response.status_code == 409: - raise BroadcastError("The broadcast has already started for the session.") + if response.status_code == 204: + return None + elif response.status_code == 400: + raise BroadcastError( + "Invalid request. This response may indicate that data in your request data is " + "invalid JSON. It may also indicate that you passed in invalid layout options. " + "Or you have exceeded the limit of five simultaneous RTMP streams for an OpenTok " + "session. Or you specified and invalid resolution." + ) + elif response.status_code == 403: + raise AuthError("Authentication error.") + elif response.status_code == 405: + raise BroadcastStreamModeError( + "Your broadcast is configured with a streamMode that does not support stream manipulation." + ) + elif response.status_code == 409: + raise BroadcastError("The broadcast has already started for the session.") else: - raise RequestError("OpenTok server error.", response.status_code) + raise RequestError("An unexpected error occurred.", response.status_code) def remove_broadcast_stream( self, broadcast_id: str, stream_id: str @@ -1601,22 +1605,23 @@ def remove_broadcast_stream( ) if response: - return Broadcast(response.json()) - elif response.status_code == 400: - raise BroadcastError( - "Invalid request. This response may indicate that data in your request data is " - "invalid JSON. It may also indicate that you passed in invalid layout options. " - "Or you have exceeded the limit of five simultaneous RTMP streams for an OpenTok " - "session. Or you specified and invalid resolution." - ) - elif response.status_code == 403: - raise AuthError("Authentication error.") - elif response.status_code == 405: - raise BroadcastStreamModeError( - "Your broadcast is configured with a streamMode that does not support stream manipulation." - ) - elif response.status_code == 409: - raise BroadcastError("The broadcast has already started for the session.") + if response.status_code == 204: + return None + elif response.status_code == 400: + raise BroadcastError( + "Invalid request. This response may indicate that data in your request data is " + "invalid JSON. It may also indicate that you passed in invalid layout options. " + "Or you have exceeded the limit of five simultaneous RTMP streams for an OpenTok " + "session. Or you specified and invalid resolution." + ) + elif response.status_code == 403: + raise AuthError("Authentication error.") + elif response.status_code == 405: + raise BroadcastStreamModeError( + "Your broadcast is configured with a streamMode that does not support stream manipulation." + ) + elif response.status_code == 409: + raise BroadcastError("The broadcast has already started for the session.") else: raise RequestError("OpenTok server error.", response.status_code) diff --git a/opentok/version.py b/opentok/version.py index 748e154..08fcda6 100644 --- a/opentok/version.py +++ b/opentok/version.py @@ -1,3 +1,3 @@ # see: http://legacy.python.org/dev/peps/pep-0440/#public-version-identifiers -__version__ = "3.6.0" +__version__ = "3.6.1" diff --git a/tests/test_archive.py b/tests/test_archive.py index df03f96..12ef505 100644 --- a/tests/test_archive.py +++ b/tests/test_archive.py @@ -1,17 +1,14 @@ import unittest -from six import text_type, u, b, PY2, PY3 -from nose.tools import raises +from six import u, PY2, PY3 from expects import * import httpretty from sure import expect import textwrap -import json import datetime -import requests import pytz from .validate_jwt import validate_jwt_header -from opentok import Client, Archive, __version__, OutputModes, StreamModes +from opentok import Client, Archive, __version__, OutputModes class OpenTokArchiveTest(unittest.TestCase): @@ -102,64 +99,31 @@ def test_stop_archive(self): expect(archive).to(have_property(u("output_mode"), OutputModes.composed)) expect(archive).to(have_property(u("url"), None)) - - @httpretty.activate def test_add_archive_stream(self): archive_id = u("ARCHIVEID") url = f"https://api.opentok.com/v2/project/{self.api_key}/archive/{archive_id}/streams" - - payload = { - "hasAudio": True, - "hasVideo": True, - "addStream": self.stream1 - } - - httpretty.register_uri(httpretty.PATCH, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - - response = requests.patch(url) - - response.status_code.should.equal(200) - response.json().should.equal({ - "hasAudio": True, - "hasVideo": True, - "addStream": self.stream1 - }) + httpretty.register_uri( + httpretty.PATCH, url, responses=[httpretty.Response(body=u(""), status=204)] + ) - response.headers["Content-Type"].should.equal("application/json") + response = self.opentok.add_archive_stream( + archive_id=archive_id, stream_id=self.stream1 + ) + assert response == None @httpretty.activate def test_remove_archive_stream(self): archive_id = u("ARCHIVEID") url = f"https://api.opentok.com/v2/project/{self.api_key}/archive/{archive_id}/streams" - - payload = { - "removeStream": self.stream1 - } - - httpretty.register_uri(httpretty.PATCH, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - - response = requests.patch(url) - - response.status_code.should.equal(200) - response.json().should.equal({ - "removeStream": self.stream1 - }) - - response.headers["Content-Type"].should.equal("application/json") + httpretty.register_uri( + httpretty.PATCH, url, responses=[httpretty.Response(body=u(""), status=204)] + ) + response = self.opentok.remove_archive_stream( + archive_id=archive_id, stream_id=self.stream1 + ) + assert response == None @httpretty.activate def test_delete_archive(self): diff --git a/tests/test_broadcast.py b/tests/test_broadcast.py index 411ffec..599d932 100644 --- a/tests/test_broadcast.py +++ b/tests/test_broadcast.py @@ -8,6 +8,7 @@ from six import u, PY2, PY3 from expects import * from opentok import Client, Broadcast, __version__, BroadcastError +from opentok.broadcast import BroadcastStreamModes from opentok.exceptions import BroadcastHLSOptionsError from .validate_jwt import validate_jwt_header @@ -92,7 +93,6 @@ def test_start_broadcast(self): ) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json")) - ) # non-deterministic json encoding. have to decode to test it properly if PY2: @@ -237,9 +237,7 @@ def test_start_broadcast_with_screenshare_type(self): ) options = { - "layout": { - "screenshareType": "verticalPresentation" - }, + "layout": {"screenshareType": "verticalPresentation"}, "maxDuration": 5400, "outputs": { "hls": {}, @@ -367,7 +365,6 @@ def test_start_broadcast_audio_only(self): ) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json")) - ) # non-deterministic json encoding. have to decode to test it properly if PY2: @@ -468,7 +465,6 @@ def test_start_broadcast_video_only(self): ) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json")) - ) # non-deterministic json encoding. have to decode to test it properly if PY2: @@ -496,143 +492,114 @@ def test_start_broadcast_video_only(self): @httpretty.activate def test_start_broadcast_with_streammode_auto(self): - url = f"https://api.opentok.com/v2/partner/{self.api_key}/broadcast" - - httpretty.register_uri(httpretty.POST, - url, - responses=[ - httpretty.Response(body=json.dumps({"stream_mode":"auto"}), - content_type="application/json", - status=200) - ]) - + url = f"https://api.opentok.com/v2/project/{self.api_key}/broadcast" - response = requests.post(url) - - response.status_code.should.equal(200) - response.json().should.equal({"stream_mode":"auto"}) - response.headers["Content-Type"].should.equal("application/json") + httpretty.register_uri( + httpretty.POST, + url, + responses=[ + httpretty.Response( + body=json.dumps({"stream_mode": "auto"}), + content_type="application/json", + status=200, + ) + ], + ) + broadcast = self.opentok.start_broadcast( + session_id=self.session_id, options={"outputs": {"hls": {}}} + ) + broadcast.stream_mode.should.equal(BroadcastStreamModes.auto) @httpretty.activate def test_add_broadcast_stream(self): broadcast_id = "BROADCASTID" - url = f"https://api.opentok.com/v2/partner/{self.api_key}/broadcast/{broadcast_id}/streams" - - payload = { - "hasAudio": True, - "hasVideo": True, - "addStream": self.stream1 - } - - httpretty.register_uri(httpretty.POST, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - - - response = requests.post(url) - - response.status_code.should.equal(200) - response.json().should.equal({ - "hasAudio": True, - "hasVideo": True, - "addStream": self.stream1 - }) - response.headers["Content-Type"].should.equal("application/json") + url = f"https://api.opentok.com/v2/project/{self.api_key}/broadcast/{broadcast_id}/streams" + httpretty.register_uri( + httpretty.PATCH, url, responses=[httpretty.Response(body=u(""), status=204)] + ) - + response = self.opentok.add_broadcast_stream( + broadcast_id=broadcast_id, stream_id=self.stream1 + ) + assert response == None @httpretty.activate def test_remove_broadcast_stream(self): broadcast_id = "BROADCASTID" - url = f"https://api.opentok.com/v2/partner/{self.api_key}/broadcast/{broadcast_id}/streams" - - payload = { - "removeStream": self.stream1 - } - - httpretty.register_uri(httpretty.POST, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - - - response = requests.post(url) - - response.status_code.should.equal(200) - response.json().should.equal({ - "removeStream": self.stream1 - }) - response.headers["Content-Type"].should.equal("application/json") + url = f"https://api.opentok.com/v2/project/{self.api_key}/broadcast/{broadcast_id}/streams" + httpretty.register_uri( + httpretty.PATCH, url, responses=[httpretty.Response(body=u(""), status=204)] + ) + response = self.opentok.add_broadcast_stream( + broadcast_id=broadcast_id, stream_id=self.stream1 + ) + assert response == None @httpretty.activate def test_update_broadcast_auto(self): broadcast_id = u("BROADCASTID") - url = f"https://api.opentok.com/v2/partner/{self.api_key}/broadcast/{broadcast_id}/streams" - + url = f"https://api.opentok.com/v2/project/{self.api_key}/broadcast/{broadcast_id}/streams" + payload = { "hasAudio": True, "hasVideo": True, - "addStream": [self.stream1, self.stream2] + "addStream": [self.stream1, self.stream2], } - - httpretty.register_uri(httpretty.PATCH, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - + + httpretty.register_uri( + httpretty.PATCH, + url, + responses=[ + httpretty.Response( + body=json.dumps(payload), + content_type="application/json", + status=200, + ) + ], + ) + response = requests.patch(url) response.status_code.should.equal(200) - response.json().should.equal({ - "hasAudio": True, - "hasVideo": True, - "addStream": [self.stream1, self.stream2] - }) + response.json().should.equal( + { + "hasAudio": True, + "hasVideo": True, + "addStream": [self.stream1, self.stream2], + } + ) response.headers["Content-Type"].should.equal("application/json") @httpretty.activate def test_update_broadcast_manual(self): broadcast_id = u("BROADCASTID") - url = f"https://api.opentok.com/v2/partner/{self.api_key}/broadcast/{broadcast_id}/streams" - - payload = { - "hasAudio": True, - "hasVideo": True, - "addStream": [self.stream1] - } - - httpretty.register_uri(httpretty.PATCH, - url, - responses=[ - httpretty.Response(body=json.dumps(payload), - content_type="application/json", - status=200) - ]) - + url = f"https://api.opentok.com/v2/project/{self.api_key}/broadcast/{broadcast_id}/streams" + + payload = {"hasAudio": True, "hasVideo": True, "addStream": [self.stream1]} + + httpretty.register_uri( + httpretty.PATCH, + url, + responses=[ + httpretty.Response( + body=json.dumps(payload), + content_type="application/json", + status=200, + ) + ], + ) + response = requests.patch(url) response.status_code.should.equal(200) - response.json().should.equal({ - "hasAudio": True, - "hasVideo": True, - "addStream": [self.stream1] - }) - - response.headers["Content-Type"].should.equal("application/json") + response.json().should.equal( + {"hasAudio": True, "hasVideo": True, "addStream": [self.stream1]} + ) + response.headers["Content-Type"].should.equal("application/json") @httpretty.activate def test_stop_broadcast(self): @@ -754,7 +721,7 @@ def test_get_broadcast(self): @httpretty.activate def test_set_broadcast_layout(self): - """ Test set_broadcast_layout() functionality """ + """Test set_broadcast_layout() functionality""" broadcast_id = u("1748b707-0a81-464c-9759-c46ad10d3734") httpretty.register_uri( @@ -778,7 +745,7 @@ def test_set_broadcast_layout(self): @httpretty.activate def test_set_broadcast_layout_with_screenshare_type(self): - """ Test set_broadcast_layout() functionality """ + """Test set_broadcast_layout() functionality""" broadcast_id = u("1748b707-0a81-464c-9759-c46ad10d3734") httpretty.register_uri( @@ -790,7 +757,9 @@ def test_set_broadcast_layout_with_screenshare_type(self): content_type=u("application/json"), ) - self.opentok.set_broadcast_layout(broadcast_id, "bestFit", screenshare_type="horizontalPresentation") + self.opentok.set_broadcast_layout( + broadcast_id, "bestFit", screenshare_type="horizontalPresentation" + ) validate_jwt_header(self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to( @@ -810,7 +779,7 @@ def test_set_broadcast_layout_with_screenshare_type(self): @httpretty.activate def test_set_custom_broadcast_layout(self): - """ Test set a custom broadcast layout specifying the 'stylesheet' parameter """ + """Test set a custom broadcast layout specifying the 'stylesheet' parameter""" broadcast_id = u("1748b707-0a81-464c-9759-c46ad10d3734") httpretty.register_uri( @@ -838,7 +807,7 @@ def test_set_custom_broadcast_layout(self): @httpretty.activate def test_set_broadcast_layout_throws_exception(self): - """ Test invalid request in set broadcast layout """ + """Test invalid request in set broadcast layout""" broadcast_id = u("1748b707-0a81-464c-9759-c46ad10d3734") httpretty.register_uri( @@ -861,7 +830,7 @@ def test_broadcast_hls_mutually_exclusive_options_error(self): """ Test invalid options in start_broadcast() method raises a BroadcastHLSOptionsError. """ - + options = { "layout": { "type": "custom", @@ -869,10 +838,7 @@ def test_broadcast_hls_mutually_exclusive_options_error(self): }, "maxDuration": 5400, "outputs": { - "hls": { - "lowLatency": True, - "dvr": True - }, + "hls": {"lowLatency": True, "dvr": True}, "rtmp": [ { "id": "foo",