Skip to content

Commit

Permalink
Moved property builder into LT quick
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Collins committed Mar 9, 2020
1 parent 5fc69b3 commit 2036157
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 63 deletions.
67 changes: 4 additions & 63 deletions examples/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,11 @@
import types
import functools

from labthings.server.quick import create_app
from labthings.server.view import View
from labthings.server.decorators import ThingProperty, PropertySchema, use_args, Doc

from labthings.server.types import value_to_field, data_dict_to_schema
from labthings.server.quick import create_app, property_of

from components.pdf_component import PdfComponent


def gen_property(
property_object, property_name, name: str = None, readonly=False, description=None
):

# Create a class name
if not name:
name = type(property_object).__name__ + f"_{property_name}"

# Create inner functions
def _get(self):
return getattr(property_object, property_name)

def _post(self, args):
setattr(property_object, property_name, args)
return getattr(property_object, property_name)

def _put(self, args):
getattr(property_object, property_name).update(args)
return getattr(property_object, property_name)

# Generate a basic property class
generated_class = type(
name,
(View, object),
{
"property_object": property_object,
"property_name": property_name,
"get": _get,
},
)

# Override read-write capabilities
if not readonly:
generated_class.post = _post
# Enable PUT requests for dictionaries
if type(getattr(property_object, property_name)) == dict:
generated_class.put = _put

# Add decorators for arguments etc
initial_property_value = getattr(property_object, property_name)
if type(initial_property_value) == dict:
property_schema = data_dict_to_schema(initial_property_value)
else:
property_schema = value_to_field(initial_property_value)

generated_class = PropertySchema(property_schema)(generated_class)
generated_class = ThingProperty(generated_class)

if description:
generated_class = Doc(description=description, summary=description)(
generated_class
)

return generated_class


# Create LabThings Flask app
app, labthing = create_app(
__name__,
Expand All @@ -77,16 +17,17 @@ def _put(self, args):
)

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

# Add routes for the API views we created
labthing.add_view(
gen_property(my_component, "magic_denoise", description="A magic denoise property"),
property_of(my_component, "magic_denoise", description="A magic denoise property"),
"/denoise",
)
labthing.add_view(
gen_property(
property_of(
my_component,
"magic_dictionary",
description="A big dictionary of little properties",
Expand Down
60 changes: 60 additions & 0 deletions labthings/server/quick.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
from .labthing import LabThing
from .exceptions import JSONExceptionHandler

from .view import View
from .types import value_to_field, data_dict_to_schema
from .decorators import ThingProperty, PropertySchema, Doc


def create_app(
import_name,
Expand Down Expand Up @@ -61,3 +65,59 @@ def create_app(
labthing.handlers["error"] = error_handler

return app, labthing


def property_of(
property_object, property_name, name: str = None, readonly=False, description=None
):

# Create a class name
if not name:
name = type(property_object).__name__ + f"_{property_name}"

# Create inner functions
def _get(self):
return getattr(property_object, property_name)

def _post(self, args):
setattr(property_object, property_name, args)
return getattr(property_object, property_name)

def _put(self, args):
getattr(property_object, property_name).update(args)
return getattr(property_object, property_name)

# Generate a basic property class
generated_class = type(
name,
(View, object),
{
"property_object": property_object,
"property_name": property_name,
"get": _get,
},
)

# Override read-write capabilities
if not readonly:
generated_class.post = _post
# Enable PUT requests for dictionaries
if type(getattr(property_object, property_name)) == dict:
generated_class.put = _put

# Add decorators for arguments etc
initial_property_value = getattr(property_object, property_name)
if type(initial_property_value) == dict:
property_schema = data_dict_to_schema(initial_property_value)
else:
property_schema = value_to_field(initial_property_value)

generated_class = PropertySchema(property_schema)(generated_class)
generated_class = ThingProperty(generated_class)

if description:
generated_class = Doc(description=description, summary=description)(
generated_class
)

return generated_class

0 comments on commit 2036157

Please sign in to comment.