auto-trainer-api 0.9.6__py3-none-any.whl → 0.9.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: auto-trainer-api
3
- Version: 0.9.6
3
+ Version: 0.9.7
4
4
  Summary: API for interfacing with the core acquisition process via platform and language agnostic message queues.
5
5
  License: AGPL-3.0-only
6
6
  Classifier: Operating System :: OS Independent
@@ -83,7 +83,7 @@ The returned `ApiCommandRequestResponse` object contains one require field
83
83
  * `result` - a value of `ApiCommandReqeustResult`
84
84
 
85
85
  There are also three optional fields
86
- * `data` - an optional dictionary with results from the command beyond success/failure (often will be None)
86
+ * `data` - an optional object with results from the command beyond success/failure (often will be None)
87
87
  * `error_code` an integer error code value if the command is not successful or can't be initiated
88
88
  * `error_message` an integer error code value if the command is not successful or can't be initiated
89
89
 
@@ -106,6 +106,18 @@ topic of `ApiTopic.COMMAND_RESULT`. The `message` argument of the `send_dict` m
106
106
  received in the `ApiCommandRequest` (the client is responsible for storing these values until needed). Note that
107
107
  those two properties are ignored for synchronous command handling, but required for asynchronous responses.
108
108
 
109
+ ## Tools
110
+
111
+ ### Client Application
112
+ `scripts/client_application.py` starts an interactive process that enables the `RpcService` as a "real" autotrainer
113
+ application would. It generates heartbeat events, can publish other events from the command line, and responds to
114
+ commands. This is primarily useful for testing remote applictions/services without running the main autotrainer
115
+ acquisition application.
116
+
117
+ ### Remote Console
118
+ `scripts/remote_console.py` starts an interactive process that connects to an `RpcService` instance in the same manner
119
+ full remote management services would. Currently, it only supports sending a small subset of the predefined
120
+ `ApiCommand` values, but may be expanded to show events and send additional commands.
109
121
 
110
122
  ## Publishing
111
123
  `python -m build`
@@ -0,0 +1,16 @@
1
+ autotrainer/api/__init__.py,sha256=SaDhy95qTzVH67pZ3qM0Uv86KoKP6Zh-V3VUHJqBBXo,686
2
+ autotrainer/api/api_event_kind.py,sha256=-suGV1kTS5gXrkOS2Yq_ahkyTgFhwhbPn8PcR7vT9CE,3647
3
+ autotrainer/api/api_options.py,sha256=LJrWqVe6JhYKw9UDL3uJcX4HTkwLW0STaNCGpPWRkoc,761
4
+ autotrainer/api/rpc_service.py,sha256=b1zseMu328sdPWJHazlfl_fC94iXy7zwmDwmv3rqNw0,18351
5
+ autotrainer/api/util.py,sha256=RfN6xMgCUahOz6RWMvSUkuw3mz0JEB2cpYoZBVdDY5M,1244
6
+ autotrainer/api/command/__init__.py,sha256=CPwRJSFU89XchwJhZ4Yw8ANYBDalb7uoMW63RxQ8NRQ,141
7
+ autotrainer/api/command/api_command.py,sha256=p5ymobZXBGiZt1RFwGZLaZnXgfZOPWTZg60Zra6fv_w,804
8
+ autotrainer/api/command/configuration_response.py,sha256=-V8vbZlgHFCwTNf3KTq5wqPWaysY2-SxdjKkUdrVVFQ,233
9
+ autotrainer/api/command/status_response.py,sha256=-Sq52Ebv8oIkzLhkIJdpgb3zKBqJXQ09aZZXTISfBQE,433
10
+ autotrainer/api/telemtry/__init__.py,sha256=gd013s0gvD2Wc-hj2tGkvQQGNR3u0f8ZGYxbYvITWfo,57
11
+ autotrainer/api/telemtry/open_telemetry_service.py,sha256=V-bDe_UX1I4iPtBgKV4R4tAAuGbsE3kyxGtr5ZD2mJc,2018
12
+ autotrainer/api/zeromq/__init__.py,sha256=L0txGZRsARnVMfuKpEg9E22WkiuoU1FRmzqMAQCqtf4,50
13
+ autotrainer/api/zeromq/zeromq_api_service.py,sha256=StThMM5JMu_Zua9_q9MzMM0xkQijyuABunADqq8yAKY,5029
14
+ auto_trainer_api-0.9.7.dist-info/METADATA,sha256=h6CvFJgjhRNpuK9debdIWVSvJWoqL2ntWq9kaytQ6cY,7065
15
+ auto_trainer_api-0.9.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ auto_trainer_api-0.9.7.dist-info/RECORD,,
@@ -4,18 +4,15 @@ API Service functionality for Autotrainer.
4
4
 
5
5
  from typing import Optional
6
6
 
7
+ from .api_event_kind import ApiEventKind
8
+ from .command import ApiCommand, ConfigurationResponse, StatusResponse
7
9
  from .api_options import ApiOptions, create_default_api_options
8
10
  from .rpc_service import ApiTopic, ApiCommandRequest, ApiCommandRequestResponse, ApiCommandReqeustResult, RpcService
9
11
 
10
- from .util import patch_uuid_encoder
11
-
12
12
 
13
13
  def create_api_service(options: ApiOptions) -> Optional[RpcService]:
14
14
  from .zeromq import ZeroMQApiService
15
15
 
16
- # Several autotrainer messages may contain a UUID, which is not handled by the default JSON encoder.
17
- # patch_uuid_encoder()
18
-
19
16
  # TODO Enable when ready
20
17
  # configure_telemetry(options.telemetry)
21
18
 
@@ -16,11 +16,20 @@ class ApiEventKind(IntEnum):
16
16
 
17
17
  # Core/System
18
18
  emergencyStop = 101
19
+ """Payload {"reason": <string>}"""
19
20
  emergencyResume = 102
21
+ """Payload {"reason": <string>}"""
20
22
 
21
23
  applicationLaunched = 201
22
24
  applicationTerminating = 202
23
25
 
26
+ acquisitionStarted = 301
27
+ acquisitionEnded = 305
28
+ calibrationDcsStarted = 310
29
+ calibrationDcsEnded = 315
30
+ calibration3dStarted = 320
31
+ calibration3dEnded = 325
32
+
24
33
  propertyChanged = 501
25
34
 
26
35
  # Behavior
@@ -111,10 +120,14 @@ class ApiEventKind(IntEnum):
111
120
 
112
121
  # Training
113
122
  trainingModeChanged = 5001
123
+ """Payload {"training_mode": ApiTrainingMode}"""
114
124
 
115
125
  trainingPlanLoad = 5101
126
+ """Payload {training_plan_id: <uuid of plan>}"""
116
127
 
117
128
  trainingPhaseEnter = 5201
129
+ """Payload {"training_phase_id": <uuid of plan>}"""
118
130
  trainingPhaseExit = 5202
131
+ """Payload {"training_phase_id": <uuid of plan>}"""
119
132
 
120
133
  trainingProgressUpdate = 5501
@@ -0,0 +1,3 @@
1
+ from .api_command import ApiCommand
2
+ from .configuration_response import ConfigurationResponse
3
+ from .status_response import StatusResponse
@@ -0,0 +1,30 @@
1
+ from enum import IntEnum
2
+
3
+
4
+ class ApiCommand(IntEnum):
5
+ """
6
+ A command value is required for all command requests.
7
+ """
8
+ NONE = 0
9
+ """No command. Can be used to verify connection or that the receiver is configured to receive commands."""
10
+
11
+ START_ACQUISITION = 100
12
+ STOP_ACQUISITION = 110
13
+
14
+ EMERGENCY_STOP = 200
15
+ EMERGENCY_RESUME = 210
16
+
17
+ GET_CONFIGURATION = 300
18
+ """Response Payload: ConfigurationResponse"""
19
+
20
+ GET_STATUS = 400
21
+ """Response Payload: StatusResponse"""
22
+
23
+ USER_DEFINED = 99999
24
+ """A custom command defined between a particular commander and receiver. Additional information can be
25
+ defined in the `data` field."""
26
+
27
+ @classmethod
28
+ def is_member(cls, value):
29
+ return value in cls._value2member_map_
30
+
@@ -0,0 +1,11 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class ConfigurationResponse:
6
+ device_id: str
7
+ configuration_location: str
8
+ data_location: str
9
+ animal_location: str
10
+ log_location: str
11
+ inference_model: str
@@ -0,0 +1,22 @@
1
+ from dataclasses import dataclass
2
+ from enum import IntEnum
3
+
4
+
5
+ class ApiAppStatus(IntEnum):
6
+ IDLE = 0
7
+ ACQUIRING = 100
8
+ CALIBRATION_DCS = 200
9
+ CALIBRATION_3D = 300
10
+
11
+
12
+ class ApiTrainingMode(IntEnum):
13
+ UNDEFINED = 0
14
+ MANUAL = 100
15
+ MANUAL_WITH_PROTOCOL = 200
16
+ AUTOMATIC = 300
17
+
18
+ @dataclass
19
+ class StatusResponse:
20
+ app_status: ApiAppStatus
21
+ training_mode: ApiTrainingMode
22
+ animal_id: str
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import logging
3
3
  import time
4
- from dataclasses import dataclass, asdict
4
+ from dataclasses import dataclass, asdict, is_dataclass
5
5
  from enum import IntEnum
6
6
  from queue import Queue, Empty
7
7
  from threading import Timer, Thread
@@ -10,11 +10,16 @@ from typing_extensions import Self
10
10
 
11
11
  import humps
12
12
 
13
+ from autotrainer.api.command.api_command import ApiCommand
13
14
  from .api_event_kind import ApiEventKind
14
15
  from .api_options import RpcOptions
15
16
 
16
17
  logger = logging.getLogger(__name__)
17
18
 
19
+ import importlib.metadata
20
+
21
+ _heartbeat_version = importlib.metadata.version("auto-trainer-api")
22
+
18
23
 
19
24
  class ApiTopic(IntEnum):
20
25
  """
@@ -40,25 +45,6 @@ class ApiTopic(IntEnum):
40
45
  """ Responses to asynchronous command handling. """
41
46
 
42
47
 
43
- class ApiCommand(IntEnum):
44
- """
45
- A command value is required for all command requests.
46
- """
47
- NONE = 0
48
- START_ACQUISITION = 100
49
- STOP_ACQUISITION = 110
50
- EMERGENCY_STOP = 130
51
- EMERGENCY_RESUME = 135
52
- """No command. Can be used to verify connection or that the receiver is configured to receive commands."""
53
- USER_DEFINED = 99999
54
- """A custom command defined between a particular commander and receiver. Additional information can be
55
- defined in the `data` field."""
56
-
57
- @classmethod
58
- def is_member(cls, value):
59
- return value in cls._value2member_map_
60
-
61
-
62
48
  @dataclass(frozen=True)
63
49
  class ApiCommandRequest:
64
50
  """
@@ -136,7 +122,7 @@ NotificationEventKinds = [ApiEventKind.emergencyStop, ApiEventKind.emergencyResu
136
122
  class ApiCommandRequestResponse:
137
123
  result: ApiCommandReqeustResult
138
124
 
139
- data: Optional[dict] = None
125
+ data: Optional[Any] = None
140
126
 
141
127
  error_code: int = 0
142
128
  error_message: Optional[str] = None
@@ -264,7 +250,7 @@ class RpcService:
264
250
  self._heartbeat_timer = None
265
251
  self._heartbeat: HeartbeatMessage = HeartbeatMessage(
266
252
  identifier=options.identifier,
267
- version="0.9.6",
253
+ version=_heartbeat_version,
268
254
  timestamp=0.0
269
255
  )
270
256
 
@@ -394,10 +380,15 @@ class RpcService:
394
380
 
395
381
  error_kind = ApiCommandRequestErrorKind.COMMAND_ERROR if client_response.error_code != 0 else ApiCommandRequestErrorKind.NONE
396
382
 
383
+ data = client_response.data
384
+
385
+ if data is not None and is_dataclass(data):
386
+ data = asdict(data)
387
+
397
388
  self._send_command_response(
398
389
  ApiCommandRequestServiceResponse(request.nonce, request.command, client_response.result,
399
- client_response.data, error_kind,
400
- client_response.error_code, client_response.error_message))
390
+ data, error_kind, client_response.error_code,
391
+ client_response.error_message))
401
392
  except Exception as e:
402
393
  self._send_command_response(
403
394
  ApiCommandRequestServiceResponse.for_exception(request.command, request.nonce, e))
@@ -5,7 +5,8 @@ from typing import Optional
5
5
  import zmq
6
6
  import humps
7
7
 
8
- from ..rpc_service import RpcService, RpcOptions, ApiTopic, ApiCommandRequestServiceResponse, ApiCommandRequest, ApiCommand
8
+ from ..rpc_service import RpcService, RpcOptions, ApiTopic, ApiCommandRequestServiceResponse, ApiCommandRequest
9
+ from autotrainer.api.command.api_command import ApiCommand
9
10
  from ..util import get_ip4_addr_str, UUIDEncoder
10
11
 
11
12
  logger = logging.getLogger(__name__)
@@ -1,12 +0,0 @@
1
- autotrainer/api/__init__.py,sha256=8GUKQ8L-gGgU8XlMztL88zwcjalregEVh__Mo6GGRg4,748
2
- autotrainer/api/api_event_kind.py,sha256=cKwMDhlTUGY6SM_A1r2vWfHIDPRHYHtSDkWdTt9oDbs,3159
3
- autotrainer/api/api_options.py,sha256=LJrWqVe6JhYKw9UDL3uJcX4HTkwLW0STaNCGpPWRkoc,761
4
- autotrainer/api/rpc_service.py,sha256=1r7RFrSgsjfZSMunq1UgA8AEP6oLXF48waM8TC-OMI4,18628
5
- autotrainer/api/util.py,sha256=RfN6xMgCUahOz6RWMvSUkuw3mz0JEB2cpYoZBVdDY5M,1244
6
- autotrainer/api/telemtry/__init__.py,sha256=gd013s0gvD2Wc-hj2tGkvQQGNR3u0f8ZGYxbYvITWfo,57
7
- autotrainer/api/telemtry/open_telemetry_service.py,sha256=V-bDe_UX1I4iPtBgKV4R4tAAuGbsE3kyxGtr5ZD2mJc,2018
8
- autotrainer/api/zeromq/__init__.py,sha256=L0txGZRsARnVMfuKpEg9E22WkiuoU1FRmzqMAQCqtf4,50
9
- autotrainer/api/zeromq/zeromq_api_service.py,sha256=WiG7B7rFJNESdDZhzxkmvHY03ei5T9PXeNgRFhJUTjg,4981
10
- auto_trainer_api-0.9.6.dist-info/METADATA,sha256=3P0jS8siCnK0uIw9MyIjvPfVSq7sPnZV3DozRmPgs8g,6332
11
- auto_trainer_api-0.9.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- auto_trainer_api-0.9.6.dist-info/RECORD,,