Skip to content

Commit 3049798

Browse files
committed
Updated documentation example app
1 parent 5a33d71 commit 3049798

File tree

2 files changed

+182
-6
lines changed

2 files changed

+182
-6
lines changed

docs/basic_usage/index.rst

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,28 @@ An example Lab Thing built from our ``PretendSpectrometer`` class, complete with
3030
3131
3232
# Make some properties and actions out of our component
33+
my_spectrometer = PretendSpectrometer()
3334
3435
# Single-shot data property
3536
labthing.build_property(
36-
my_component, # Python object
37+
my_spectrometer, # Python object
3738
"data", # Objects attribute name
38-
"/data", # URL to bind the property to
3939
description="A single-shot measurement",
4040
readonly=True,
4141
schema=fields.List(fields.Number())
4242
)
4343
4444
# Magic denoise property
4545
labthing.build_property(
46-
my_component, # Python object
46+
my_spectrometer, # Python object
4747
"magic_denoise", # Objects attribute name
48-
"/denoise", # URL to bind the property to
4948
description="A magic denoise property",
5049
schema=fields.Int(min=100, max=500, example=200)
5150
)
5251
5352
# Averaged measurement action
5453
labthing.build_action(
55-
my_component.average_data, # Python function
56-
"/average", # URL to bind the action to
54+
my_spectrometer.average_data, # Python function
5755
description="Take an averaged measurement",
5856
args={ # How do we convert from the request input to function arguments?
5957
"n": fields.Int(description="Number of averages to take", example=5, default=5)
@@ -67,6 +65,97 @@ An example Lab Thing built from our ``PretendSpectrometer`` class, complete with
6765
Server(app).run()
6866
6967
68+
Once started, the app will build and serve a full web API, and generate the following Thing Description:
69+
70+
.. code-block:: JSON
71+
72+
{
73+
"@context": [
74+
"https://www.w3.org/2019/wot/td/v1",
75+
"https://iot.mozilla.org/schemas/"
76+
],
77+
"id": "http://127.0.0.1:7486/",
78+
"base": "http://127.0.0.1:7486/",
79+
"title": "My PretendSpectrometer API",
80+
"description": "LabThing API for PretendSpectrometer",
81+
"properties": {
82+
"pretendSpectrometerData": {
83+
"title": "PretendSpectrometer_data",
84+
"description": "A single-shot measurement",
85+
"readOnly": true,
86+
"links": [{
87+
"href": "/properties/PretendSpectrometer/data"
88+
}],
89+
"forms": [{
90+
"op": "readproperty",
91+
"htv:methodName": "GET",
92+
"href": "/properties/PretendSpectrometer/data",
93+
"contentType": "application/json"
94+
}],
95+
"type": "array",
96+
"items": {
97+
"type": "number",
98+
"format": "decimal"
99+
}
100+
},
101+
"pretendSpectrometerMagicDenoise": {
102+
"title": "PretendSpectrometer_magic_denoise",
103+
"description": "A magic denoise property",
104+
"links": [{
105+
"href": "/properties/PretendSpectrometer/magic_denoise"
106+
}],
107+
"forms": [{
108+
"op": "readproperty",
109+
"htv:methodName": "GET",
110+
"href": "/properties/PretendSpectrometer/magic_denoise",
111+
"contentType": "application/json"
112+
},
113+
{
114+
"op": "writeproperty",
115+
"htv:methodName": "PUT",
116+
"href": "/properties/PretendSpectrometer/magic_denoise",
117+
"contentType": "application/json"
118+
}
119+
],
120+
"type": "number",
121+
"format": "integer",
122+
"min": 100,
123+
"max": 500,
124+
"example": 200
125+
}
126+
},
127+
"actions": {
128+
"averageDataAction": {
129+
"title": "average_data_action",
130+
"description": "Take an averaged measurement",
131+
"links": [{
132+
"href": "/actions/PretendSpectrometer/average_data"
133+
}],
134+
"forms": [{
135+
"op": "invokeaction",
136+
"htv:methodName": "POST",
137+
"href": "/actions/PretendSpectrometer/average_data",
138+
"contentType": "application/json"
139+
}],
140+
"input": {
141+
"type": "object",
142+
"properties": {
143+
"n": {
144+
"type": "number",
145+
"format": "integer",
146+
"default": 5,
147+
"description": "Number of averages to take",
148+
"example": 5
149+
}
150+
}
151+
}
152+
}
153+
},
154+
"links": [...],
155+
"securityDefinitions": {...},
156+
"security": "nosec_sc"
157+
}
158+
70159
71160
For completeness of the examples, our ``PretendSpectrometer`` class code is:
72161

examples/docs_example.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
from labthings.server.quick import create_app
2+
from labthings.server import fields
3+
4+
import random
5+
import math
6+
import time
7+
8+
9+
class PretendSpectrometer:
10+
def __init__(self):
11+
self.x_range = range(-100, 100)
12+
self.magic_denoise = 200
13+
14+
def make_spectrum(self, x, mu=0.0, sigma=25.0):
15+
"""
16+
Generate a noisy gaussian function (to act as some pretend data)
17+
18+
Our noise is inversely proportional to self.magic_denoise
19+
"""
20+
x = float(x - mu) / sigma
21+
return (
22+
math.exp(-x * x / 2.0) / math.sqrt(2.0 * math.pi) / sigma
23+
+ (1 / self.magic_denoise) * random.random()
24+
)
25+
26+
@property
27+
def data(self):
28+
"""Return a 1D data trace."""
29+
return [self.make_spectrum(x) for x in self.x_range]
30+
31+
def average_data(self, n: int):
32+
"""Average n-sets of data. Emulates a measurement that may take a while."""
33+
summed_data = self.data
34+
35+
for _ in range(n):
36+
summed_data = [summed_data[i] + el for i, el in enumerate(self.data)]
37+
time.sleep(0.25)
38+
39+
summed_data = [i / n for i in summed_data]
40+
41+
return summed_data
42+
43+
44+
# Create LabThings Flask app
45+
app, labthing = create_app(
46+
__name__,
47+
title="My PretendSpectrometer API",
48+
description="LabThing API for PretendSpectrometer",
49+
version="0.1.0",
50+
)
51+
52+
53+
# Make some properties and actions out of our component
54+
my_spectrometer = PretendSpectrometer()
55+
56+
# Single-shot data property
57+
labthing.build_property(
58+
my_spectrometer, # Python object
59+
"data", # Objects attribute name
60+
description="A single-shot measurement",
61+
readonly=True,
62+
schema=fields.List(fields.Number()),
63+
)
64+
65+
# Magic denoise property
66+
labthing.build_property(
67+
my_spectrometer, # Python object
68+
"magic_denoise", # Objects attribute name
69+
description="A magic denoise property",
70+
schema=fields.Int(min=100, max=500, example=200),
71+
)
72+
73+
# Averaged measurement action
74+
labthing.build_action(
75+
my_spectrometer.average_data, # Python function
76+
description="Take an averaged measurement",
77+
args={ # How do we convert from the request input to function arguments?
78+
"n": fields.Int(description="Number of averages to take", example=5, default=5)
79+
},
80+
)
81+
82+
83+
# Start the app
84+
if __name__ == "__main__":
85+
from labthings.server.wsgi import Server
86+
87+
Server(app).run()

0 commit comments

Comments
 (0)