55Only methods decorated with ` action() ` are exposed to clients.
66
77``` py title="Actions" linenums="1"
8- -- 8 < -- " docs/howto/code/thing_example_2.py:168:172"
9- -- 8 < -- " docs/howto/code/thing_example_2.py:365:374"
10- -- 8 < -- " docs/howto/code/thing_example_2.py:510:513"
11- -- 8 < -- " docs/howto/code/thing_example_2.py:446:451"
12- -- 8 < -- " docs/howto/code/thing_example_2.py:455:456"
13- -- 8 < -- " docs/howto/code/thing_example_2.py:375:380"
8+ -- 8 < -- " docs/beginners-guide/code/thing_example_2.py:189:192"
9+ -- 8 < -- " docs/beginners-guide/code/thing_example_2.py:431:445"
10+ -- 8 < -- " docs/beginners-guide/code/thing_example_2.py:643:646"
11+ -- 8 < -- " docs/beginners-guide/code/thing_example_2.py:542:546"
1412```
1513
1614Arguments are loosely typed and may need to be constrained with a schema based
@@ -21,21 +19,132 @@ on the robustness the developer is expecting in their application:
2119
2220 === "Single Argument"
2321
22+ Just specify the expected type of the argument (with or without name)
23+
2424 ```py title="Input Schema" linenums="1"
25- --8<-- "docs/howto /code/thing_example_2.py:168:172 "
26- --8<-- "docs/howto /code/thing_example_2.py:189:205 "
25+ --8<-- "docs/beginners-guide /code/thing_example_2.py:189:192 "
26+ --8<-- "docs/beginners-guide /code/thing_example_2.py:210:222 "
2727 ```
2828
29+ ???+ note "JSON schema seen in Thing Description"
30+
31+ ```py
32+ GentecOpticalEnergyMeter.set_sensor_model.to_affordance().json()
33+ ```
34+
35+ ```json
36+ {
37+ "description": "Set the attached sensor to the meter under control. Sensor should be defined as a class and added to the AllowedSensors dict.",
38+ "input": {
39+ "type": "string",
40+ "enum": ["QE25LP-S-MB", "QE12LP-S-MB-QED-D0"]
41+ },
42+ "synchronous": True
43+ }
44+ ```
45+
2946 === "Multiple Arguments"
3047
48+ You need to specify the action argument names under the `properties` field with `type` as `object`.
49+ Names not found in the `properties` field can be subsumed under python spread operator `**kwargs` if necessary.
50+
3151 ```py title="Input Schema with Multiple Arguments" linenums="1"
32- --8<-- "docs/howto/code/thing_example_3.py:47:75"
33- --8<-- "docs/howto/code/thing_example_3.py:78:80"
34- --8<-- "docs/howto/code/thing_example_3.py:83:83"
35- --8<-- "docs/howto/code/thing_example_3.py:188:195"
36- --8<-- "docs/howto/code/thing_example_3.py:219:219"
52+ --8<-- "docs/beginners-guide/code/thing_example_3.py:57:85"
53+ --8<-- "docs/beginners-guide/code/thing_example_3.py:87:87"
54+ --8<-- "docs/beginners-guide/code/thing_example_3.py:213:226"
55+ --8<-- "docs/beginners-guide/code/thing_example_3.py:247:247"
3756 ```
3857
58+ ???+ note "JSON schema seen in Thing Description"
59+
60+ ```py
61+ Picoscope6000.set_channel.to_affordance().json()
62+ ```
63+
64+ ```json
65+ {
66+ "description": "Set the parameter for a channel. https://www.picotech.com/download/manuals/picoscope-6000-series-a-api-programmers-guide.pdf",
67+ "input": {
68+ "type": "object",
69+ "properties": {
70+ "channel": {"type": "string", "enum": ["A", "B", "C", "D"]},
71+ "enabled": {"type": "boolean"},
72+ "voltage_range": {
73+ "type": "string",
74+ "enum": [
75+ "10mV",
76+ "20mV",
77+ "50mV",
78+ "100mV",
79+ "200mV",
80+ "500mV",
81+ "1V",
82+ "2V",
83+ "5V",
84+ "10V",
85+ "20V",
86+ "50V",
87+ "MAX_RANGES"
88+ ]},
89+ "offset": {"type": "number"},
90+ "coupling": {"type": "string", "enum": ["AC", "DC"]},
91+ "bw_limiter": {"type": "string", "enum": ["full", "20MHz"]}
92+ }
93+ },
94+ "synchronous": True
95+ }
96+ ```
97+
98+ === "Return Type"
99+
100+ ```py title="With Return Type"
101+ --8<-- "docs/beginners-guide/code/thing_example_3.py:22:55"
102+ --8<-- "docs/beginners-guide/code/thing_example_3.py:87:87"
103+ --8<-- "docs/beginners-guide/code/thing_example_3.py:349:356"
104+ ```
105+
106+ ???+ note "JSON schema seen in Thing Description"
107+
108+ ```py
109+ Picoscope6000.get_analogue_offset.to_affordance().json()
110+ ```
111+
112+ ```json
113+ {
114+ "description": "analogue offset for a voltage range and coupling",
115+ "synchronous": True,
116+ "input": {
117+ "type": "object",
118+ "properties": {
119+ "voltage_range": {
120+ "type": "string",
121+ "enum": ["10mV",
122+ "20mV",
123+ "50mV",
124+ "100mV",
125+ "200mV",
126+ "500mV",
127+ "1V",
128+ "2V",
129+ "5V",
130+ "10V",
131+ "20V",
132+ "50V",
133+ "MAX_RANGES"
134+ ]
135+ },
136+ "coupling": {"type": "string", "enum": ["AC", "DC"]}
137+ }
138+ },
139+ "output": {
140+ "type": "array",
141+ "minItems": 2,
142+ "maxItems": 2,
143+ "items": {"type": "number"}
144+ },
145+ }
146+ ```
147+
39148=== "pydantic"
40149
41150 === "Single Argument"
@@ -52,38 +161,21 @@ However, a schema is optional and it only matters that
52161the method signature is matching when requested from a client. To enable this, set global attribute ` allow_relaxed_schema_actions=True ` . This setting is used especially when a schema is useful for validation of arguments but not available - not for methods with no arguments.
53162
54163``` py title="Relaxed or Unavailable Schema for Actions" linenums="1"
55- -- 8 < -- " docs/howto /code/thing_example_2.py:168:172"
56- -- 8 < -- " docs/howto /code/thing_example_2.py:558:559"
164+ -- 8 < -- " docs/beginners-guide /code/thing_example_2.py:168:172"
165+ -- 8 < -- " docs/beginners-guide /code/thing_example_2.py:558:559"
57166```
58167
59- The return value must be validated by the clients themselves. While a schema for the return value can be supplied, there is no separate validation performed on the server:
60-
61- === "JSON Schema"
62-
63- ```py title="Output Schema" linenums="1"
64- --8<-- "docs/howto/code/thing_example_3.py:22:36"
65- --8<-- "docs/howto/code/thing_example_3.py:38:45"
66- --8<-- "docs/howto/code/thing_example_3.py:78:80"
67- --8<-- "docs/howto/code/thing_example_3.py:83:83"
68- --8<-- "docs/howto/code/thing_example_3.py:307:323"
69- ```
70-
71- === "pydantic"
72-
73- ```py title="" linenums="1"
74- ```
75-
76168It is always possible to custom validate the arguments after invoking the action:
77169
78170``` py title="Custom Validation" linenums="1"
79- -- 8 < -- " docs/howto /code/actions/parameterized_function.py:3:3"
80- -- 8 < -- " docs/howto /code/actions/parameterized_function.py:9:27"
171+ -- 8 < -- " docs/beginners-guide /code/actions/parameterized_function.py:3:3"
172+ -- 8 < -- " docs/beginners-guide /code/actions/parameterized_function.py:9:27"
81173```
82174
83175The last and least preferred possibility is to use ` ParameterizedFunction ` :
84176
85177``` py title="Parameterized Function" linenums="1"
86- -- 8 < -- " docs/howto /code/actions/parameterized_function.py:52:"
178+ -- 8 < -- " docs/beginners-guide /code/actions/parameterized_function.py:52:"
87179```
88180
89181` ParameterizedFunction ` (s) are classes that implement the ` __call__ ` method and whose arguments are type defined using the same objects as properties. However, this type definition using ` Property ` object do not make these properties of the ` Thing ` . The implementation follows convention used by ` param ` where the
@@ -97,11 +189,11 @@ client side, there is no difference between invoking a normal action and an acti
97189=== "server"
98190
99191 ```py title="Custom Validation" linenums="1"
100- --8<-- "docs/howto /code/actions/parameterized_function.py:38:44"
192+ --8<-- "docs/beginners-guide /code/actions/parameterized_function.py:38:44"
101193 ```
102194
103195=== "client"
104196
105197 ```py title="Custom Validation" linenums="1"
106- --8<-- "docs/howto /code/actions/parameterized_function.py:30:36"
198+ --8<-- "docs/beginners-guide /code/actions/parameterized_function.py:30:36"
107199 ```
0 commit comments