request and event data now returned as dataclasses

unit tests updated accordingly
This commit is contained in:
onyx-and-iris 2022-07-27 22:44:40 +01:00
parent f5c2293dce
commit 20851c3880
9 changed files with 52 additions and 25 deletions

13
.gitignore vendored
View File

@ -22,6 +22,19 @@ wheels/
*.egg *.egg
MANIFEST MANIFEST
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Environments # Environments
.env .env
.venv .venv

View File

@ -16,15 +16,15 @@ class Observer:
def on_current_program_scene_changed(self, data): def on_current_program_scene_changed(self, data):
"""The current program scene has changed.""" """The current program scene has changed."""
print(f"Switched to scene {data['sceneName']}") print(f"Switched to scene {data.scene_name}")
def on_scene_created(self, data): def on_scene_created(self, data):
"""A new scene has been created.""" """A new scene has been created."""
print(f"scene {data['sceneName']} has been created") print(f"scene {data.scene_name} has been created")
def on_input_mute_state_changed(self, data): def on_input_mute_state_changed(self, data):
"""An input's mute state has changed.""" """An input's mute state has changed."""
print(f"{data['inputName']} mute toggled") print(f"{data.input_name} mute toggled")
def on_exit_started(self, data): def on_exit_started(self, data):
"""OBS has begun the shutdown process.""" """OBS has begun the shutdown process."""

View File

@ -16,7 +16,7 @@ class Observer:
def on_current_program_scene_changed(self, data): def on_current_program_scene_changed(self, data):
"""The current program scene has changed.""" """The current program scene has changed."""
print(f"{self.event_identifier}: {data}") print(f"{self.event_identifier}: {data.scene_name}")
def version(): def version():

View File

@ -5,7 +5,7 @@ import obsstudio_sdk as obs
def main(): def main():
resp = cl.get_scene_list() resp = cl.get_scene_list()
scenes = reversed(tuple(di["sceneName"] for di in resp["scenes"])) scenes = reversed(tuple(di.get("sceneName") for di in resp.scenes))
for sc in scenes: for sc in scenes:
print(f"Switching to scene {sc}") print(f"Switching to scene {sc}")

View File

@ -1,8 +1,6 @@
import base64 import base64
import hashlib import hashlib
import json import json
import time
from enum import IntEnum
from pathlib import Path from pathlib import Path
from random import randint from random import randint

View File

@ -1,6 +1,7 @@
import re
from typing import Callable, Iterable, Union from typing import Callable, Iterable, Union
from .util import as_dataclass, to_camel_case, to_snake_case
class Callback: class Callback:
"""Adds support for callbacks""" """Adds support for callbacks"""
@ -10,25 +11,17 @@ class Callback:
self._callbacks = list() self._callbacks = list()
def to_camel_case(self, s):
s = "".join(word.title() for word in s.split("_"))
return s[2:]
def to_snake_case(self, s):
s = re.sub(r"(?<!^)(?=[A-Z])", "_", s).lower()
return f"on_{s}"
def get(self) -> list: def get(self) -> list:
"""returns a list of registered events""" """returns a list of registered events"""
return [self.to_camel_case(fn.__name__) for fn in self._callbacks] return [to_camel_case(fn.__name__) for fn in self._callbacks]
def trigger(self, event, data): def trigger(self, event, data):
"""trigger callback on update""" """trigger callback on update"""
for fn in self._callbacks: for fn in self._callbacks:
if fn.__name__ == self.to_snake_case(event): if fn.__name__ == f"on_{to_snake_case(event)}":
fn(data.get("eventData")) fn(as_dataclass(event, data.get("eventData")))
def register(self, fns: Union[Iterable, Callable]): def register(self, fns: Union[Iterable, Callable]):
"""registers callback functions""" """registers callback functions"""

View File

@ -1,5 +1,6 @@
from .baseclient import ObsClient from .baseclient import ObsClient
from .error import OBSSDKError from .error import OBSSDKError
from .util import as_dataclass
""" """
A class to interact with obs-websocket requests A class to interact with obs-websocket requests
@ -23,7 +24,7 @@ class ReqClient(object):
error += (f"With message: {response['requestStatus']['comment']}",) error += (f"With message: {response['requestStatus']['comment']}",)
raise OBSSDKError("\n".join(error)) raise OBSSDKError("\n".join(error))
if "responseData" in response: if "responseData" in response:
return response["responseData"] return as_dataclass(response["requestType"], response["responseData"])
def get_version(self): def get_version(self):
""" """

22
obsstudio_sdk/util.py Normal file
View File

@ -0,0 +1,22 @@
import re
from dataclasses import dataclass
def to_camel_case(s):
s = "".join(word.title() for word in s.split("_"))
return s[2:]
def to_snake_case(s):
s = re.sub(r"(?<!^)(?=[A-Z])", "_", s).lower()
return f"{s}"
def as_dataclass(identifier, data):
return dataclass(
type(
f"{identifier}Dataclass",
(),
{**{to_snake_case(k): v for k, v in data.items()}},
)
)

View File

@ -8,8 +8,8 @@ class TestRequests:
def test_get_version(self): def test_get_version(self):
resp = req_cl.get_version() resp = req_cl.get_version()
assert "obsVersion" in resp assert hasattr(resp, "obs_version")
assert "obsWebSocketVersion" in resp assert hasattr(resp, "obs_web_socket_version")
@pytest.mark.parametrize( @pytest.mark.parametrize(
"scene", "scene",
@ -22,7 +22,7 @@ class TestRequests:
def test_current_program_scene(self, scene): def test_current_program_scene(self, scene):
req_cl.set_current_program_scene(scene) req_cl.set_current_program_scene(scene)
resp = req_cl.get_current_program_scene() resp = req_cl.get_current_program_scene()
assert resp["currentProgramSceneName"] == scene assert resp.current_program_scene_name == scene
@pytest.mark.parametrize( @pytest.mark.parametrize(
"state", "state",
@ -34,7 +34,7 @@ class TestRequests:
def test_studio_mode_enabled(self, state): def test_studio_mode_enabled(self, state):
req_cl.set_studio_mode_enabled(state) req_cl.set_studio_mode_enabled(state)
resp = req_cl.get_studio_mode_enabled() resp = req_cl.get_studio_mode_enabled()
assert resp["studioModeEnabled"] == state assert resp.studio_mode_enabled == state
@pytest.mark.parametrize( @pytest.mark.parametrize(
"name,data", "name,data",
@ -46,4 +46,4 @@ class TestRequests:
def test_persistent_data(self, name, data): def test_persistent_data(self, name, data):
req_cl.set_persistent_data("OBS_WEBSOCKET_DATA_REALM_PROFILE", name, data) req_cl.set_persistent_data("OBS_WEBSOCKET_DATA_REALM_PROFILE", name, data)
resp = req_cl.get_persistent_data("OBS_WEBSOCKET_DATA_REALM_PROFILE", name) resp = req_cl.get_persistent_data("OBS_WEBSOCKET_DATA_REALM_PROFILE", name)
assert resp["slotValue"] == data assert resp.slot_value == data