Skip to content

Commit 2036157

Browse files
author
Joel Collins
committed
Moved property builder into LT quick
1 parent 5fc69b3 commit 2036157

File tree

2 files changed

+64
-63
lines changed

2 files changed

+64
-63
lines changed

examples/builder.py

Lines changed: 4 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,11 @@
22
import types
33
import functools
44

5-
from labthings.server.quick import create_app
6-
from labthings.server.view import View
7-
from labthings.server.decorators import ThingProperty, PropertySchema, use_args, Doc
8-
9-
from labthings.server.types import value_to_field, data_dict_to_schema
5+
from labthings.server.quick import create_app, property_of
106

117
from components.pdf_component import PdfComponent
128

139

14-
def gen_property(
15-
property_object, property_name, name: str = None, readonly=False, description=None
16-
):
17-
18-
# Create a class name
19-
if not name:
20-
name = type(property_object).__name__ + f"_{property_name}"
21-
22-
# Create inner functions
23-
def _get(self):
24-
return getattr(property_object, property_name)
25-
26-
def _post(self, args):
27-
setattr(property_object, property_name, args)
28-
return getattr(property_object, property_name)
29-
30-
def _put(self, args):
31-
getattr(property_object, property_name).update(args)
32-
return getattr(property_object, property_name)
33-
34-
# Generate a basic property class
35-
generated_class = type(
36-
name,
37-
(View, object),
38-
{
39-
"property_object": property_object,
40-
"property_name": property_name,
41-
"get": _get,
42-
},
43-
)
44-
45-
# Override read-write capabilities
46-
if not readonly:
47-
generated_class.post = _post
48-
# Enable PUT requests for dictionaries
49-
if type(getattr(property_object, property_name)) == dict:
50-
generated_class.put = _put
51-
52-
# Add decorators for arguments etc
53-
initial_property_value = getattr(property_object, property_name)
54-
if type(initial_property_value) == dict:
55-
property_schema = data_dict_to_schema(initial_property_value)
56-
else:
57-
property_schema = value_to_field(initial_property_value)
58-
59-
generated_class = PropertySchema(property_schema)(generated_class)
60-
generated_class = ThingProperty(generated_class)
61-
62-
if description:
63-
generated_class = Doc(description=description, summary=description)(
64-
generated_class
65-
)
66-
67-
return generated_class
68-
69-
7010
# Create LabThings Flask app
7111
app, labthing = create_app(
7212
__name__,
@@ -77,16 +17,17 @@ def _put(self, args):
7717
)
7818

7919
# Attach an instance of our component
20+
# Usually a Python object controlling some piece of hardware
8021
my_component = PdfComponent()
8122
labthing.add_component(my_component, "org.labthings.example.mycomponent")
8223

8324
# Add routes for the API views we created
8425
labthing.add_view(
85-
gen_property(my_component, "magic_denoise", description="A magic denoise property"),
26+
property_of(my_component, "magic_denoise", description="A magic denoise property"),
8627
"/denoise",
8728
)
8829
labthing.add_view(
89-
gen_property(
30+
property_of(
9031
my_component,
9132
"magic_dictionary",
9233
description="A big dictionary of little properties",

labthings/server/quick.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
from .labthing import LabThing
55
from .exceptions import JSONExceptionHandler
66

7+
from .view import View
8+
from .types import value_to_field, data_dict_to_schema
9+
from .decorators import ThingProperty, PropertySchema, Doc
10+
711

812
def create_app(
913
import_name,
@@ -61,3 +65,59 @@ def create_app(
6165
labthing.handlers["error"] = error_handler
6266

6367
return app, labthing
68+
69+
70+
def property_of(
71+
property_object, property_name, name: str = None, readonly=False, description=None
72+
):
73+
74+
# Create a class name
75+
if not name:
76+
name = type(property_object).__name__ + f"_{property_name}"
77+
78+
# Create inner functions
79+
def _get(self):
80+
return getattr(property_object, property_name)
81+
82+
def _post(self, args):
83+
setattr(property_object, property_name, args)
84+
return getattr(property_object, property_name)
85+
86+
def _put(self, args):
87+
getattr(property_object, property_name).update(args)
88+
return getattr(property_object, property_name)
89+
90+
# Generate a basic property class
91+
generated_class = type(
92+
name,
93+
(View, object),
94+
{
95+
"property_object": property_object,
96+
"property_name": property_name,
97+
"get": _get,
98+
},
99+
)
100+
101+
# Override read-write capabilities
102+
if not readonly:
103+
generated_class.post = _post
104+
# Enable PUT requests for dictionaries
105+
if type(getattr(property_object, property_name)) == dict:
106+
generated_class.put = _put
107+
108+
# Add decorators for arguments etc
109+
initial_property_value = getattr(property_object, property_name)
110+
if type(initial_property_value) == dict:
111+
property_schema = data_dict_to_schema(initial_property_value)
112+
else:
113+
property_schema = value_to_field(initial_property_value)
114+
115+
generated_class = PropertySchema(property_schema)(generated_class)
116+
generated_class = ThingProperty(generated_class)
117+
118+
if description:
119+
generated_class = Doc(description=description, summary=description)(
120+
generated_class
121+
)
122+
123+
return generated_class

0 commit comments

Comments
 (0)