From 3adf0944813e0491e18bb296241c2fbe5b783845 Mon Sep 17 00:00:00 2001 From: Adem <34811741+aatikturk@users.noreply.github.com> Date: Mon, 29 May 2023 10:34:40 +0000 Subject: [PATCH 1/7] Added 'timeout' option for baseclient. bumped version --- obsws_python/baseclient.py | 9 ++++++--- obsws_python/version.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/obsws_python/baseclient.py b/obsws_python/baseclient.py index 10e9d12..9bf8143 100644 --- a/obsws_python/baseclient.py +++ b/obsws_python/baseclient.py @@ -15,7 +15,7 @@ class ObsClient: logger = logging.getLogger("baseclient.obsclient") def __init__(self, **kwargs): - defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0} + defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0, "timeout":3} if not any(key in kwargs for key in ("host", "port", "password")): kwargs |= self._conn_from_toml() kwargs = defaultkwargs | kwargs @@ -29,7 +29,7 @@ class ObsClient: ) self.ws = websocket.WebSocket() - self.ws.connect(f"ws://{self.host}:{self.port}") + self.ws.connect(f"ws://{self.host}:{self.port}", timeout=self.timeout) self.server_hello = json.loads(self.ws.recv()) def _conn_from_toml(self) -> dict: @@ -105,7 +105,10 @@ class ObsClient: if req_data: payload["d"]["requestData"] = req_data self.logger.debug(f"Sending request {payload}") - self.ws.send(json.dumps(payload)) + try: + self.ws.send(json.dumps(payload)) + except TimeoutError: + raise OBSSDKError("Timeout while trying to send the request") response = json.loads(self.ws.recv()) self.logger.debug(f"Response received {response}") return response["d"] diff --git a/obsws_python/version.py b/obsws_python/version.py index 841aad2..8fb4690 100644 --- a/obsws_python/version.py +++ b/obsws_python/version.py @@ -1 +1 @@ -version = "1.4.2" +version = "1.4.3" From 15559fdb330c79fe788c325176a53b3b7db9201c Mon Sep 17 00:00:00 2001 From: Adem <34811741+aatikturk@users.noreply.github.com> Date: Mon, 29 May 2023 10:48:41 +0000 Subject: [PATCH 2/7] updated readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fa8c6b..fab24a0 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ By default the clients connect with parameters: - `host`: "localhost" - `port`: 4455 - `password`: "" - +- `timeout`: 3 You may override these parameters by storing them in a toml config file or passing them as keyword arguments. Order of precedence: keyword arguments then config file then default values. @@ -41,6 +41,7 @@ A valid `config.toml` might look like this: host = "localhost" port = 4455 password = "mystrongpass" +timeout = 3 ``` It should be placed in your user home directory. @@ -53,7 +54,7 @@ Example `__main__.py`: import obsws_python as obs # pass conn info if not in config.toml -cl = obs.ReqClient(host='localhost', port=4455, password='mystrongpass') +cl = obs.ReqClient(host='localhost', port=4455, password='mystrongpass', timeout=3) # Toggle the mute state of your Mic input cl.toggle_input_mute('Mic/Aux') From 64a7c2b7530b56db422ff59c2759a1e20b63f9ec Mon Sep 17 00:00:00 2001 From: Adem <34811741+aatikturk@users.noreply.github.com> Date: Wed, 14 Jun 2023 01:09:44 +0300 Subject: [PATCH 3/7] update readme and base client --- README.md | 2 +- obsws_python/baseclient.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fab24a0..46b8849 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ By default the clients connect with parameters: - `host`: "localhost" - `port`: 4455 - `password`: "" -- `timeout`: 3 + You may override these parameters by storing them in a toml config file or passing them as keyword arguments. Order of precedence: keyword arguments then config file then default values. diff --git a/obsws_python/baseclient.py b/obsws_python/baseclient.py index 9bf8143..17b85a0 100644 --- a/obsws_python/baseclient.py +++ b/obsws_python/baseclient.py @@ -7,7 +7,7 @@ from random import randint from typing import Optional import websocket - +from websocket._exceptions import WebSocketTimeoutException from .error import OBSSDKError @@ -15,7 +15,7 @@ class ObsClient: logger = logging.getLogger("baseclient.obsclient") def __init__(self, **kwargs): - defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0, "timeout":3} + defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0, "timeout":None} if not any(key in kwargs for key in ("host", "port", "password")): kwargs |= self._conn_from_toml() kwargs = defaultkwargs | kwargs @@ -107,8 +107,8 @@ class ObsClient: self.logger.debug(f"Sending request {payload}") try: self.ws.send(json.dumps(payload)) - except TimeoutError: + response = json.loads(self.ws.recv()) + except WebSocketTimeoutException : raise OBSSDKError("Timeout while trying to send the request") - response = json.loads(self.ws.recv()) self.logger.debug(f"Response received {response}") return response["d"] From 82b6cdcd04738f551208758cdb188c43dddbc709 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 19 Jun 2023 17:44:10 +0100 Subject: [PATCH 4/7] add error class OBSSDKTimeoutError --- obsws_python/error.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/obsws_python/error.py b/obsws_python/error.py index 67885a4..42719b1 100644 --- a/obsws_python/error.py +++ b/obsws_python/error.py @@ -1,4 +1,6 @@ class OBSSDKError(Exception): - """general errors""" + """Exception raised when general errors occur""" - pass + +class OBSSDKTimeoutError(Exception): + """Exception raised when a connection times out""" From 9e3c1d3f372bb9401c2a97225228d806eb9d77bc Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 19 Jun 2023 17:45:49 +0100 Subject: [PATCH 5/7] raise timeout errors. added some error/exception logging. added timeout parameter to repr methods. --- obsws_python/baseclient.py | 33 ++++++++++++++++++++++++--------- obsws_python/events.py | 11 +++++++++-- obsws_python/reqs.py | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/obsws_python/baseclient.py b/obsws_python/baseclient.py index 17b85a0..4f47d4b 100644 --- a/obsws_python/baseclient.py +++ b/obsws_python/baseclient.py @@ -7,15 +7,22 @@ from random import randint from typing import Optional import websocket -from websocket._exceptions import WebSocketTimeoutException -from .error import OBSSDKError +from websocket import WebSocketTimeoutException + +from .error import OBSSDKError, OBSSDKTimeoutError class ObsClient: logger = logging.getLogger("baseclient.obsclient") def __init__(self, **kwargs): - defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0, "timeout":None} + defaultkwargs = { + "host": "localhost", + "port": 4455, + "password": "", + "subs": 0, + "timeout": None, + } if not any(key in kwargs for key in ("host", "port", "password")): kwargs |= self._conn_from_toml() kwargs = defaultkwargs | kwargs @@ -23,14 +30,21 @@ class ObsClient: setattr(self, attr, val) self.logger.info( - "Connecting with parameters: host='{host}' port={port} password='{password}' subs={subs}".format( + "Connecting with parameters: host='{host}' port={port} password='{password}' subs={subs} timeout={timeout}".format( **self.__dict__ ) ) - self.ws = websocket.WebSocket() - self.ws.connect(f"ws://{self.host}:{self.port}", timeout=self.timeout) - self.server_hello = json.loads(self.ws.recv()) + try: + self.ws = websocket.WebSocket() + self.ws.connect(f"ws://{self.host}:{self.port}", timeout=self.timeout) + self.server_hello = json.loads(self.ws.recv()) + except ValueError as e: + self.logger.error(f"{type(e).__name__}: {e}") + raise + except (ConnectionRefusedError, WebSocketTimeoutException) as e: + self.logger.exception(f"{type(e).__name__}: {e}") + raise def _conn_from_toml(self) -> dict: try: @@ -108,7 +122,8 @@ class ObsClient: try: self.ws.send(json.dumps(payload)) response = json.loads(self.ws.recv()) - except WebSocketTimeoutException : - raise OBSSDKError("Timeout while trying to send the request") + except WebSocketTimeoutException as e: + self.logger.exception(f"{type(e).__name__}: {e}") + raise OBSSDKTimeoutError("Timeout while trying to send the request") from e self.logger.debug(f"Response received {response}") return response["d"] diff --git a/obsws_python/events.py b/obsws_python/events.py index 9a942e6..a358fe7 100644 --- a/obsws_python/events.py +++ b/obsws_python/events.py @@ -3,8 +3,11 @@ import logging import time from threading import Thread +from websocket import WebSocketTimeoutException + from .baseclient import ObsClient from .callback import Callback +from .error import OBSSDKTimeoutError from .subs import Subs """ @@ -30,7 +33,7 @@ class EventClient: def __repr__(self): return type( self - ).__name__ + "(host='{host}', port={port}, password='{password}', subs={subs})".format( + ).__name__ + "(host='{host}', port={port}, password='{password}', subs={subs}, timeout={timeout})".format( **self.base_client.__dict__, ) @@ -49,7 +52,11 @@ class EventClient: """ self.running = True while self.running: - event = json.loads(self.base_client.ws.recv()) + try: + event = json.loads(self.base_client.ws.recv()) + except WebSocketTimeoutException as e: + self.logger.exception(f"{type(e).__name__}: {e}") + raise OBSSDKTimeoutError("Timeout while waiting for event") from e self.logger.debug(f"Event received {event}") type_, data = ( event["d"].get("eventType"), diff --git a/obsws_python/reqs.py b/obsws_python/reqs.py index 9650e95..fb7a809 100644 --- a/obsws_python/reqs.py +++ b/obsws_python/reqs.py @@ -28,7 +28,7 @@ class ReqClient: def __repr__(self): return type( self - ).__name__ + "(host='{host}', port={port}, password='{password}')".format( + ).__name__ + "(host='{host}', port={port}, password='{password}', timeout={timeout})".format( **self.base_client.__dict__, ) From d84d30b75207b1cd1a0160220550f42ba26f8892 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 19 Jun 2023 17:46:43 +0100 Subject: [PATCH 6/7] update readme Errors section --- .gitignore | 5 ++++- README.md | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f07d212..6918ff5 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,7 @@ venv.bak/ # Test/config quick.py -config.toml \ No newline at end of file +config.toml +obsws.log + +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index 46b8849..4ae670b 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ By default the clients connect with parameters: - `host`: "localhost" - `port`: 4455 - `password`: "" +- `timeout`: None You may override these parameters by storing them in a toml config file or passing them as keyword arguments. @@ -41,7 +42,6 @@ A valid `config.toml` might look like this: host = "localhost" port = 4455 password = "mystrongpass" -timeout = 3 ``` It should be placed in your user home directory. @@ -132,6 +132,8 @@ If a request fails an `OBSSDKError` will be raised with a status code. For a full list of status codes refer to [Codes](https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md#requeststatus) +If a timeout occurs during sending/receiving a request or receiving an event an `OBSSDKTimeoutError` will be raised. + ### Logging If you want to see the raw messages simply set log level to DEBUG From 491a26aaf7fc2099deed8bd9afb6463833ae7f98 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 19 Jun 2023 17:51:16 +0100 Subject: [PATCH 7/7] minor ver bump --- obsws_python/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/obsws_python/version.py b/obsws_python/version.py index 8fb4690..e3a0f01 100644 --- a/obsws_python/version.py +++ b/obsws_python/version.py @@ -1 +1 @@ -version = "1.4.3" +version = "1.5.0"