Switched to ActionView and PropertyView from decorators
This commit is contained in:
parent
677b08d509
commit
1819ca6a9c
18 changed files with 57 additions and 98 deletions
|
|
@ -9,12 +9,11 @@ Thing Actions "invoke a function of the Thing, which manipulates state (e.g., to
|
|||
|
||||
Actions should be *triggered* with POST requests *only*. Ideally, a view corresponding to an action should only support POST requests.
|
||||
|
||||
Like properties, we use a class decorator to identify a view as an action: ``@ThingAction``. For example, a view to perform a "quick-capture" action may look like:
|
||||
Like properties, we use a special view class to identify a view as an action: ``ActionView``. For example, a view to perform a "quick-capture" action may look like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ThingAction
|
||||
class QuickCaptureAPI(View):
|
||||
class QuickCaptureAPI(ActionView):
|
||||
"""
|
||||
Take an image capture and return it without saving
|
||||
"""
|
||||
|
|
@ -44,8 +43,6 @@ Like properties, we use a class decorator to identify a view as an action: ``@Th
|
|||
|
||||
In this example, we are also making use of the ``@doc_response`` decorator, to document that our successful response (HTTP code 200) will return data with a mimetype ``image/jpeg``, as well as ``@use_args`` to accept optional parameters with POST requests.
|
||||
|
||||
Again like properties, the ``@ThingAction`` decorator serves only to add documentation.
|
||||
|
||||
Complete example
|
||||
----------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from labthings.server.extensions import BaseExtension
|
||||
from labthings.server.find import find_component
|
||||
from labthings.server.view import View
|
||||
from labthings.server.view import View, PropertyView
|
||||
|
||||
from labthings.server.decorators import (
|
||||
use_args,
|
||||
|
|
@ -36,8 +36,7 @@ def rename(microscope, new_name):
|
|||
## Extension views
|
||||
|
||||
# Since we only have a GET method here, it'll register as a read-only property
|
||||
@ThingProperty
|
||||
class ExampleIdentifyView(View):
|
||||
class ExampleIdentifyView(PropertyView):
|
||||
# Format our returned object using MicroscopeIdentifySchema
|
||||
@marshal_with(MicroscopeIdentifySchema())
|
||||
def get(self):
|
||||
|
|
@ -52,11 +51,10 @@ class ExampleIdentifyView(View):
|
|||
return microscope
|
||||
|
||||
|
||||
@ThingProperty
|
||||
# We can use a single schema for all methods if the input and output will be formatted identically
|
||||
# Eg. Here, we will always expect a "name" string argument, and always return a "name" string attribute
|
||||
@PropertySchema({"name": fields.String(required=True, example="My Example Microscope")})
|
||||
class ExampleRenameView(View):
|
||||
class ExampleRenameView(PropertyView):
|
||||
def get(self):
|
||||
"""
|
||||
Show the current microscope name
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from labthings.server.extensions import BaseExtension
|
||||
from labthings.server.find import find_component
|
||||
from labthings.server.view import View
|
||||
from labthings.server.view import View, ActionView, PropertyView
|
||||
|
||||
from labthings.server.decorators import (
|
||||
use_args,
|
||||
|
|
@ -41,8 +41,7 @@ def rename(microscope, new_name):
|
|||
## Extension views
|
||||
|
||||
# Since we only have a GET method here, it'll register as a read-only property
|
||||
@ThingProperty
|
||||
class ExampleIdentifyView(View):
|
||||
class ExampleIdentifyView(PropertyView):
|
||||
# Format our returned object using MicroscopeIdentifySchema
|
||||
@marshal_with(MicroscopeIdentifySchema())
|
||||
def get(self):
|
||||
|
|
@ -57,11 +56,10 @@ class ExampleIdentifyView(View):
|
|||
return microscope
|
||||
|
||||
|
||||
@ThingProperty
|
||||
# We can use a single schema for all methods if the input and output will be formatted identically
|
||||
# Eg. Here, we will always expect a "name" string argument, and always return a "name" string attribute
|
||||
@PropertySchema({"name": fields.String(required=True, example="My Example Microscope")})
|
||||
class ExampleRenameView(View):
|
||||
class ExampleRenameView(PropertyView):
|
||||
def get(self):
|
||||
"""
|
||||
Show the current microscope name
|
||||
|
|
@ -89,8 +87,7 @@ class ExampleRenameView(View):
|
|||
return microscope
|
||||
|
||||
|
||||
@ThingAction
|
||||
class QuickCaptureAPI(View):
|
||||
class QuickCaptureAPI(ActionView):
|
||||
"""
|
||||
Take an image capture and return it without saving
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from labthings.server.extensions import BaseExtension
|
||||
from labthings.server.find import find_component
|
||||
from labthings.server.view import View
|
||||
from labthings.server.view import View, ActionView
|
||||
|
||||
from labthings.server.decorators import (
|
||||
use_args,
|
||||
|
|
@ -66,8 +66,7 @@ def timelapse(microscope, n_images, t_between):
|
|||
## Extension views
|
||||
|
||||
|
||||
@ThingAction
|
||||
class TimelapseAPI(View):
|
||||
class TimelapseAPI(ActionView):
|
||||
"""
|
||||
Take a series of images in a timelapse
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from labthings.server.extensions import BaseExtension
|
||||
from labthings.server.find import find_component
|
||||
from labthings.server.view import View
|
||||
from labthings.server.view import View, ActionView
|
||||
|
||||
from labthings.server.decorators import (
|
||||
use_args,
|
||||
|
|
@ -68,8 +68,7 @@ def timelapse(microscope, n_images, t_between):
|
|||
## Extension views
|
||||
|
||||
|
||||
@ThingAction
|
||||
class TimelapseAPI(View):
|
||||
class TimelapseAPI(ActionView):
|
||||
"""
|
||||
Take a series of images in a timelapse, running as a background task
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -14,13 +14,12 @@ The property description for a view will be generated automatically from your av
|
|||
Defining Thing Properties
|
||||
-------------------------
|
||||
|
||||
In order to register a view as a Thing property, we use the ``@ThingProperty`` decorator, like so:
|
||||
In order to register a view as a Thing property, we use the ``PropertyView`` class, like so:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Since we only have a GET method here, it'll register as a read-only property
|
||||
@ThingProperty
|
||||
class ExampleIdentifyView(View):
|
||||
class ExampleIdentifyView(PropertyView):
|
||||
# Format our returned object using MicroscopeIdentifySchema
|
||||
@marshal_with(MicroscopeIdentifySchema())
|
||||
def get(self):
|
||||
|
|
@ -78,11 +77,10 @@ We will implement the ``@PropertySchema`` decorator in our ``ExampleRenameView``
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
@ThingProperty
|
||||
# We can use a single schema for all methods if the input and output will be formatted identically
|
||||
# Eg. Here, we will always expect a "name" string argument, and always return a "name" string attribute
|
||||
@PropertySchema({"name": fields.String(required=True, example="My Example Microscope")})
|
||||
class ExampleRenameView(View):
|
||||
class ExampleRenameView(PropertyView):
|
||||
def get(self):
|
||||
"""
|
||||
Show the current microscope name
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ We get around these issues by making use of background tasks, and component lock
|
|||
Background tasks
|
||||
----------------
|
||||
|
||||
Tasks are introduced to manage long-running functions in a way that does not block HTTP requests. Any API Action will automatically run as a background task (that is, any View that subclasses `ActionView`, or uses the `@ThingAction` decorator).
|
||||
Tasks are introduced to manage long-running functions in a way that does not block HTTP requests. Any API Action will automatically run as a background task (that is, any View that subclasses `ActionView`).
|
||||
|
||||
Internally, the ``tasks`` submodule stores a list of all requested tasks, and their states. This state stores the running status of the task (if itis idle, running, error, or success), information about the start and end times, a unique task ID, and, upon completion, the return value of the long-running function.
|
||||
|
||||
|
|
@ -30,11 +30,9 @@ An example of a long running task may look like:
|
|||
.. code-block:: python
|
||||
|
||||
...
|
||||
from labthings.tasks import taskify
|
||||
from labthings.server.decorators import ThingAction
|
||||
from labthings.server.view import ActionView
|
||||
|
||||
@ThingAction
|
||||
class SlowAPI(View):
|
||||
class SlowAPI(ActionView):
|
||||
def post(self):
|
||||
# Return the task object.
|
||||
return long_running_function(function_argument_1, function_argument_2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue