learning-loop-node 0.20.0__py3-none-any.whl → 0.20.2__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.
@@ -185,3 +185,4 @@ class DetectorStatus():
185
185
  target_model: Optional[str]
186
186
  errors: Dict
187
187
  operation_mode: str
188
+ node_version: Optional[str] = None
@@ -52,6 +52,7 @@ class DetectorNode(Node):
52
52
  uuid: Optional[str] = None, use_backdoor_controls: bool = False) -> None:
53
53
  super().__init__(name, uuid=uuid, node_type='detector', needs_login=False, needs_sio=False)
54
54
  self._detector_factory = detector_factory
55
+ self.node_version: Optional[str] = os.environ.get('NODE_VERSION')
55
56
  self._detector: _DetectorState = _Initializing()
56
57
  self._exclusive_model_build: bool = os.environ.get('EXCLUSIVE_MODEL_BUILD', '0').lower() in ('1', 'true')
57
58
  self._remaining_init_attempts: int = 2
@@ -409,6 +410,7 @@ class DetectorNode(Node):
409
410
  current_model=current_model,
410
411
  target_model=target_model_version,
411
412
  model_format=self._detector_factory.model_format,
413
+ node_version=self.node_version,
412
414
  )
413
415
 
414
416
  self.log_status_on_change(status.state, status)
@@ -19,7 +19,7 @@ async def put_operation_mode(request: Request):
19
19
 
20
20
  Example Usage
21
21
 
22
- curl -X PUT -d "check_for_updates" http://localhost/operation_mode
22
+ curl -X PUT -d "idle" http://localhost/operation_mode
23
23
  curl -X PUT -d "detecting" http://localhost/operation_mode
24
24
  '''
25
25
 
@@ -79,9 +79,12 @@ class TrainerLogic(TrainerLogicGeneric):
79
79
 
80
80
  except TrainingError:
81
81
  logging.exception('Exception in trainer_logic._train')
82
- await self.executor.stop_and_wait()
83
82
  self.training.training_state = previous_state
84
83
  raise
84
+ finally:
85
+ # shield so the subprocess is stopped even when the task is cancelled (e.g. on abort())
86
+ if self._executor and self._executor.is_running():
87
+ await asyncio.shield(self.executor.stop_and_wait())
85
88
 
86
89
  async def _do_detections(self) -> None:
87
90
  context = self.training.context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: learning_loop_node
3
- Version: 0.20.0
3
+ Version: 0.20.2
4
4
  Summary: Python Library for Nodes which connect to the Zauberzeug Learning Loop
5
5
  Author-email: Zauberzeug GmbH <info@zauberzeug.com>
6
6
  License: MIT
@@ -140,6 +140,27 @@ The endpoint returns None if the upload was successful and an error message othe
140
140
 
141
141
  For both ways to upload an image, the tag `picked_by_system` is automatically added to the image metadata.
142
142
 
143
+ ### Node and model information
144
+
145
+ The detector has a REST endpoint that reports what the node is currently doing and which model it has loaded:
146
+
147
+ `curl http://localhost/about`
148
+
149
+ The response contains:
150
+
151
+ - `operation_mode`: the current operation mode (`startup`, `idle` or `detecting`)
152
+ - `state`: the state of the node (e.g. `idle`, `online`, `detecting`)
153
+ - `model_info`: information about the loaded model (id, organization, project, version, categories, resolution, model size), or `null` if no model is loaded yet
154
+ - `target_model`: the model version the detector is trying to load, or `null` if none is set
155
+ - `version_control`: the model versioning mode (`follow_loop`, `specific_version` or `pause`)
156
+
157
+ The same information is available via the socketio event `about`:
158
+ `sio.emit('about')`
159
+
160
+ Use this endpoint if you need the model uuid or its categories. If you only need the version numbers, use `/model_version` (see below).
161
+
162
+ All REST endpoints of the node are also listed in the automatically generated API documentation at `http://localhost/docs`.
163
+
143
164
  ### Changing the model versioning mode
144
165
 
145
166
  The detector can be configured to one of the following behaviors:
@@ -167,6 +188,22 @@ The model versioning configuration can also be changed via a socketio event:
167
188
  There is also a GET endpoint to fetch the current model versioning configuration:
168
189
  `sio.emit('get_model_version')` or `curl http://localhost/model_version`
169
190
 
191
+ ### Changing the operation mode
192
+
193
+ The operation mode controls whether the detector may load a new model:
194
+
195
+ - `startup`: used until the first model is loaded
196
+ - `idle`: the detector checks for and performs model updates
197
+ - `detecting`: the detector runs detections and does not load new models
198
+
199
+ The mode can be read and changed via a REST endpoint. Example Usage:
200
+
201
+ - Fetch the current operation mode: `curl http://localhost/operation_mode`
202
+ - Allow model updates: `curl -X PUT -d "idle" http://localhost/operation_mode`
203
+ - Block model updates: `curl -X PUT -d "detecting" http://localhost/operation_mode`
204
+
205
+ The GET request returns the mode as plain text. The PUT request returns status code 422 if the given value is not one of the three modes above.
206
+
170
207
  ### Changing the outbox mode
171
208
 
172
209
  If the autoupload is set to `all` or `filtered` (selected) images and the corresponding detections are saved on HDD (the outbox). A background thread will upload the images and detections to the Learning Loop. The outbox is located in the `outbox` folder in the root directory of the node. The outbox can be cleared by deleting the files in the folder.
@@ -12,13 +12,13 @@ learning_loop_node/data_classes/__init__.py,sha256=_2dxfVkkI9kNM955Y7ZE8RLgfpegZ
12
12
  learning_loop_node/data_classes/annotation_data.py,sha256=NfMlTv2_5AfVY_JDM4tbjETFjSN2S2I2LJJPMMcDT50,966
13
13
  learning_loop_node/data_classes/annotations.py,sha256=ha7uuWmZqW-LU2vYrkvfnaVpvf5C2xdm826IVVBu0w0,1848
14
14
  learning_loop_node/data_classes/detections.py,sha256=hGSKc1elk4Drp4XUjQ3F9HGeRpyLvA0q064b-S9lIug,5335
15
- learning_loop_node/data_classes/general.py,sha256=GQ6vPEIm4qqBV4RZT_YS_dPeKMdbCKo6Pe5-e4Cg3_k,7295
15
+ learning_loop_node/data_classes/general.py,sha256=y_seXgqCWGoUCFzwZKt8eG8rAlANIG8VhzVVivZLklU,7334
16
16
  learning_loop_node/data_classes/image_metadata.py,sha256=4FFs89iZAfr2Jh-40QqZ_GGmJ8hl_W61eHcCqHflJLE,2293
17
17
  learning_loop_node/data_classes/socket_response.py,sha256=tIdt-oYf6ULoJIDYQCecNM9OtWR6_wJ9tL0Ksu83Vko,655
18
18
  learning_loop_node/data_classes/training.py,sha256=TybwcCDf_NUaDUaOj30lPm-7Z3Qk9XFRibEX5qIv96Y,5737
19
19
  learning_loop_node/detector/__init__.py,sha256=wroy0W1X5MX16C-peA-UHYrcdXet7GhleIlC_Pqa6hI,128
20
20
  learning_loop_node/detector/detector_logic.py,sha256=XJaHNiw5PaHoCWnJ-qsxdUELLevvztYx54TQ8KcHl18,1479
21
- learning_loop_node/detector/detector_node.py,sha256=CIHbBmKf49wxxxhrITCENeL72Wm-sJdZQV5x9_6ZlUc,35716
21
+ learning_loop_node/detector/detector_node.py,sha256=As8QW2LaR81hsZePONAuf0RBNfoDEBEF18tIRM_-evs,35834
22
22
  learning_loop_node/detector/exceptions.py,sha256=C6KbNPlSbtfgDrZx2Hbhm7Suk9jVoR3fMRCO0CkrMsQ,196
23
23
  learning_loop_node/detector/outbox.py,sha256=6F0MjFM-zNX-xWP_YGbmU0UYuyb0odsX_OcAxMPSzS0,12288
24
24
  learning_loop_node/detector/inbox_filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -29,7 +29,7 @@ learning_loop_node/detector/rest/about.py,sha256=evHJ2svUZY_DFz0FSef5u9c5KW4Uc3G
29
29
  learning_loop_node/detector/rest/backdoor_controls.py,sha256=ZNaFOvC0OLWNtcLiG-NIqS_y1kkLP4csgk3CHhp8Gis,885
30
30
  learning_loop_node/detector/rest/detect.py,sha256=BHcQbSuC1sYHRKl2wNchiasb3A4HJk9tVia11e9TS6Y,2597
31
31
  learning_loop_node/detector/rest/model_version_control.py,sha256=P4FOG0U9HT6QtCoNt-1s1pT6drtgdVjGZWEuCAyuNmA,1370
32
- learning_loop_node/detector/rest/operation_mode.py,sha256=1_xfutA_6nzdb4Q_jZiHQ5m_wA83bcG5jSIy-sfNIvk,1575
32
+ learning_loop_node/detector/rest/operation_mode.py,sha256=eHOqbPdyfgzLtlz8sYs3WjESQ_kvxEIEP-cMuDQnsDI,1562
33
33
  learning_loop_node/detector/rest/outbox_mode.py,sha256=H8coDNbgLGEfXmKQrhtXWeUHBAHpnrdZktuHXQz0xis,1148
34
34
  learning_loop_node/detector/rest/upload.py,sha256=MditQ4Tu9PRzW6vhO-I9TJcnjOFpD83XnHx-6uUURkU,1708
35
35
  learning_loop_node/enums/__init__.py,sha256=tjSrhztIQ8W656_QuXfTbbVNtH_wDXP5hpYZgzfgRhc,285
@@ -50,12 +50,12 @@ learning_loop_node/trainer/exceptions.py,sha256=vbuoE6kssLQuA8zd3LiDHmZglP6E2IJJ
50
50
  learning_loop_node/trainer/executor.py,sha256=XQ1TwgOF2pQv7bgzSaljDWG4I1ySjYXL8r9c_p9MX1Q,3947
51
51
  learning_loop_node/trainer/io_helpers.py,sha256=zWl0-HLP8zxOG3ybm76vXgEozULj_1QRl95jkrF126k,7255
52
52
  learning_loop_node/trainer/test_executor.py,sha256=6BVGDN_6f5GEMMEvDLSG1yzMybSvgXaP5uYpSfsVPP0,2224
53
- learning_loop_node/trainer/trainer_logic.py,sha256=pcVQXVICEZ0Tu6WbMtuciOCETMeQAq8SAoCj3sEF0-Y,8479
53
+ learning_loop_node/trainer/trainer_logic.py,sha256=BgkeDEVaRVuRETYMt2rKe5cspExTgnO7LXNVYVbIcsw,8679
54
54
  learning_loop_node/trainer/trainer_logic_generic.py,sha256=IRP68ZGpnOX4OS03OwB7HmTUvk6nbBRmCjMCVupGE_Q,27196
55
55
  learning_loop_node/trainer/trainer_node.py,sha256=ZnydfHJ2ehAhb821Xke_09qthCE3vDf7iqeYUrliSSo,4938
56
56
  learning_loop_node/trainer/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  learning_loop_node/trainer/rest/backdoor_controls.py,sha256=ZnK8ypY5r_q0-YZbtaOxhQThzuZvMsQHM5gJGESd_dE,5131
58
- learning_loop_node-0.20.0.dist-info/METADATA,sha256=mrnQ8e97A5zQTk8HSj_LxVzZ9rQq711XRQteman88lw,15383
59
- learning_loop_node-0.20.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
60
- learning_loop_node-0.20.0.dist-info/top_level.txt,sha256=nS5qiFc4stVF_VXVCVJxZnrqVOv3IGX5-_E3sLby6OE,19
61
- learning_loop_node-0.20.0.dist-info/RECORD,,
58
+ learning_loop_node-0.20.2.dist-info/METADATA,sha256=wx_DLGWg99OEC3AUymtRgjVo7k1BHz-aOSPCjPunCg4,17175
59
+ learning_loop_node-0.20.2.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
60
+ learning_loop_node-0.20.2.dist-info/top_level.txt,sha256=nS5qiFc4stVF_VXVCVJxZnrqVOv3IGX5-_E3sLby6OE,19
61
+ learning_loop_node-0.20.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.1)
2
+ Generator: setuptools (83.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5