|
13 | 13 | import httpx |
14 | 14 | from urllib.parse import urlparse, urljoin |
15 | 15 |
|
| 16 | +import numpy as np |
16 | 17 | from pydantic import BaseModel |
17 | 18 |
|
18 | 19 | from .outputs import ClientBlobOutput |
@@ -159,7 +160,9 @@ def set_property(self, path: str, value: Any) -> None: |
159 | 160 | r = self.client.put(urljoin(self.path, path), json=value) |
160 | 161 | r.raise_for_status() |
161 | 162 |
|
162 | | - def invoke_action(self, path: str, **kwargs: Any) -> Any: |
| 163 | + def invoke_action( |
| 164 | + self, path: str, labthings_typehint: str | None, **kwargs: Any |
| 165 | + ) -> Any: |
163 | 166 | r"""Invoke an action on the Thing. |
164 | 167 |
|
165 | 168 | This method will make the initial POST request to invoke an action, |
@@ -205,7 +208,7 @@ def invoke_action(self, path: str, **kwargs: Any) -> Any: |
205 | 208 | href=invocation["output"]["href"], |
206 | 209 | client=self.client, |
207 | 210 | ) |
208 | | - return invocation["output"] |
| 211 | + return _adjust_type(invocation["output"], labthings_typehint) |
209 | 212 | else: |
210 | 213 | raise RuntimeError(f"Action did not complete successfully: {invocation}") |
211 | 214 |
|
@@ -276,6 +279,15 @@ class Client(cls): # type: ignore[valid-type, misc] |
276 | 279 | return Client |
277 | 280 |
|
278 | 281 |
|
| 282 | +def _adjust_type(value: Any, labthings_typehint: str | None) -> Any: |
| 283 | + """Adjust the return type based on labthings_typehint.""" |
| 284 | + if labthings_typehint is None: |
| 285 | + return value |
| 286 | + if labthings_typehint == "ndarray": |
| 287 | + return np.array(value) |
| 288 | + raise ValueError(f"No type of {labthings_typehint} known") |
| 289 | + |
| 290 | + |
279 | 291 | class PropertyClientDescriptor: |
280 | 292 | """A base class for properties on `.ThingClient` objects.""" |
281 | 293 |
|
@@ -361,9 +373,12 @@ def add_action(cls: type[ThingClient], action_name: str, action: dict) -> None: |
361 | 373 | :param action: a dictionary representing the action, in :ref:`wot_td` |
362 | 374 | format. |
363 | 375 | """ |
| 376 | + labthings_typehint = action["output"].get("format", None) |
364 | 377 |
|
365 | 378 | def action_method(self: ThingClient, **kwargs: Any) -> Any: |
366 | | - return self.invoke_action(action_name, **kwargs) |
| 379 | + return self.invoke_action( |
| 380 | + action_name, labthings_typehint=labthings_typehint, **kwargs |
| 381 | + ) |
367 | 382 |
|
368 | 383 | if "output" in action and "type" in action["output"]: |
369 | 384 | action_method.__annotations__["return"] = action["output"]["type"] |
|
0 commit comments