Skip to content

Commit 5a33d71

Browse files
committed
Added automatic URL generation for interaction builders
1 parent 1735ccd commit 5a33d71

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

examples/builder.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@
2929
labthing.build_property(
3030
my_component, # Python object
3131
"magic_denoise", # Objects attribute name
32-
"/denoise", # URL to bind the property to
3332
description="A magic denoise property",
3433
semtype=semantics.moz.LevelProperty(100, 500, example=200),
3534
)
3635

3736
labthing.build_property(
3837
my_component, # Python object
3938
"magic_dictionary", # Objects attribute name
40-
"/dictionary", # URL to bind the property to
4139
description="A big dictionary of little properties",
4240
schema={ # Property is a dictionary, with these value types
4341
"voltage": fields.Int(),
@@ -51,7 +49,6 @@
5149

5250
labthing.build_action(
5351
my_component.average_data, # Python function
54-
"/average", # URL to bind the action to
5552
description="Take an averaged measurement",
5653
safe=True, # Is the state of the Thing unchanged by calling the action?
5754
idempotent=True, # Can the action be called repeatedly with the same result?,
@@ -60,7 +57,6 @@
6057
},
6158
)
6259

63-
6460
# Start the app
6561
if __name__ == "__main__":
6662
from labthings.server.wsgi import Server

src/labthings/labthing.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from .default_views.root import RootView
3434
from .default_views.sockets import socket_handler
3535

36-
from .utilities import camel_to_snake
36+
from .utilities import camel_to_snake, url_for_property, url_for_action
3737

3838
from typing import Callable
3939

@@ -394,11 +394,15 @@ def add_root_link(self, view, rel, kwargs=None, params=None):
394394

395395
# Convenience methods
396396
def build_property(
397-
self, property_object: object, property_name: str, *urls, **kwargs
397+
self, property_object: object, property_name: str, urls: list = None, **kwargs
398398
):
399+
if urls is None:
400+
urls = [url_for_property(property_object, property_name)]
399401
self.add_view(property_of(property_object, property_name, **kwargs), *urls)
400402

401-
def build_action(self, function: Callable, *urls, **kwargs):
403+
def build_action(self, function: Callable, urls: list = None, **kwargs):
404+
if urls is None:
405+
urls = [url_for_action(function)]
402406
self.add_view(action_from(function, **kwargs), *urls)
403407

404408
def spawn_action(self, *args, **kwargs):

src/labthings/utilities.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import copy
1010
import time
1111
import typing
12+
import inspect
1213
from functools import reduce
14+
from typing import Callable
1315

1416
PY3 = sys.version_info > (3,)
1517

@@ -302,3 +304,20 @@ def path_relative_to(source_file, *paths):
302304
paths {str} -- Paths to add to source file location
303305
"""
304306
return os.path.join(os.path.abspath(os.path.dirname(source_file)), *paths)
307+
308+
309+
def get_class_that_defined_method(meth):
310+
for cls in inspect.getmro(meth.im_class):
311+
if meth.__name__ in cls.__dict__:
312+
return cls
313+
return None
314+
315+
316+
def url_for_property(property_object: object, property_name: str):
317+
return f"/properties/{property_object.__class__.__name__}/{property_name}"
318+
319+
320+
def url_for_action(function: Callable):
321+
full_name = getattr(function, "__qualname__", None) or function.__name__
322+
full_name_safe = full_name.replace(".", "/")
323+
return f"/actions/{full_name_safe}"

0 commit comments

Comments
 (0)