Merge pull request #27 from aatikturk/25-question-set-timeout-for-connection-request

Added 'timeout' option for  baseclient
This commit is contained in:
Onyx and Iris 2023-06-19 18:25:12 +01:00 committed by GitHub
commit 4e45de17ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 16 deletions

3
.gitignore vendored
View File

@ -48,3 +48,6 @@ venv.bak/
# Test/config # Test/config
quick.py quick.py
config.toml config.toml
obsws.log
.vscode/

View File

@ -27,6 +27,7 @@ By default the clients connect with parameters:
- `host`: "localhost" - `host`: "localhost"
- `port`: 4455 - `port`: 4455
- `password`: "" - `password`: ""
- `timeout`: None
You may override these parameters by storing them in a toml config file or passing them as keyword arguments. You may override these parameters by storing them in a toml config file or passing them as keyword arguments.
@ -53,7 +54,7 @@ Example `__main__.py`:
import obsws_python as obs import obsws_python as obs
# pass conn info if not in config.toml # 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 # Toggle the mute state of your Mic input
cl.toggle_input_mute('Mic/Aux') cl.toggle_input_mute('Mic/Aux')
@ -131,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) 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 ### Logging
If you want to see the raw messages simply set log level to DEBUG If you want to see the raw messages simply set log level to DEBUG

View File

@ -7,15 +7,22 @@ from random import randint
from typing import Optional from typing import Optional
import websocket import websocket
from websocket import WebSocketTimeoutException
from .error import OBSSDKError from .error import OBSSDKError, OBSSDKTimeoutError
class ObsClient: class ObsClient:
logger = logging.getLogger("baseclient.obsclient") logger = logging.getLogger("baseclient.obsclient")
def __init__(self, **kwargs): def __init__(self, **kwargs):
defaultkwargs = {"host": "localhost", "port": 4455, "password": "", "subs": 0} defaultkwargs = {
"host": "localhost",
"port": 4455,
"password": "",
"subs": 0,
"timeout": None,
}
if not any(key in kwargs for key in ("host", "port", "password")): if not any(key in kwargs for key in ("host", "port", "password")):
kwargs |= self._conn_from_toml() kwargs |= self._conn_from_toml()
kwargs = defaultkwargs | kwargs kwargs = defaultkwargs | kwargs
@ -23,14 +30,21 @@ class ObsClient:
setattr(self, attr, val) setattr(self, attr, val)
self.logger.info( 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.__dict__
) )
) )
self.ws = websocket.WebSocket() try:
self.ws.connect(f"ws://{self.host}:{self.port}") self.ws = websocket.WebSocket()
self.server_hello = json.loads(self.ws.recv()) 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: def _conn_from_toml(self) -> dict:
try: try:
@ -105,7 +119,11 @@ class ObsClient:
if req_data: if req_data:
payload["d"]["requestData"] = req_data payload["d"]["requestData"] = req_data
self.logger.debug(f"Sending request {payload}") self.logger.debug(f"Sending request {payload}")
self.ws.send(json.dumps(payload)) try:
response = json.loads(self.ws.recv()) self.ws.send(json.dumps(payload))
response = json.loads(self.ws.recv())
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}") self.logger.debug(f"Response received {response}")
return response["d"] return response["d"]

View File

@ -1,4 +1,6 @@
class OBSSDKError(Exception): class OBSSDKError(Exception):
"""general errors""" """Exception raised when general errors occur"""
pass
class OBSSDKTimeoutError(Exception):
"""Exception raised when a connection times out"""

View File

@ -3,8 +3,11 @@ import logging
import time import time
from threading import Thread from threading import Thread
from websocket import WebSocketTimeoutException
from .baseclient import ObsClient from .baseclient import ObsClient
from .callback import Callback from .callback import Callback
from .error import OBSSDKTimeoutError
from .subs import Subs from .subs import Subs
""" """
@ -30,7 +33,7 @@ class EventClient:
def __repr__(self): def __repr__(self):
return type( return type(
self 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__, **self.base_client.__dict__,
) )
@ -49,7 +52,11 @@ class EventClient:
""" """
self.running = True self.running = True
while self.running: 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}") self.logger.debug(f"Event received {event}")
type_, data = ( type_, data = (
event["d"].get("eventType"), event["d"].get("eventType"),

View File

@ -28,7 +28,7 @@ class ReqClient:
def __repr__(self): def __repr__(self):
return type( return type(
self self
).__name__ + "(host='{host}', port={port}, password='{password}')".format( ).__name__ + "(host='{host}', port={port}, password='{password}', timeout={timeout})".format(
**self.base_client.__dict__, **self.base_client.__dict__,
) )

View File

@ -1 +1 @@
version = "1.4.2" version = "1.5.0"