dtlpy 1.115.44__py3-none-any.whl → 1.117.6__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.
Files changed (238) hide show
  1. dtlpy/__init__.py +491 -491
  2. dtlpy/__version__.py +1 -1
  3. dtlpy/assets/__init__.py +26 -26
  4. dtlpy/assets/code_server/config.yaml +2 -2
  5. dtlpy/assets/code_server/installation.sh +24 -24
  6. dtlpy/assets/code_server/launch.json +13 -13
  7. dtlpy/assets/code_server/settings.json +2 -2
  8. dtlpy/assets/main.py +53 -53
  9. dtlpy/assets/main_partial.py +18 -18
  10. dtlpy/assets/mock.json +11 -11
  11. dtlpy/assets/model_adapter.py +83 -83
  12. dtlpy/assets/package.json +61 -61
  13. dtlpy/assets/package_catalog.json +29 -29
  14. dtlpy/assets/package_gitignore +307 -307
  15. dtlpy/assets/service_runners/__init__.py +33 -33
  16. dtlpy/assets/service_runners/converter.py +96 -96
  17. dtlpy/assets/service_runners/multi_method.py +49 -49
  18. dtlpy/assets/service_runners/multi_method_annotation.py +54 -54
  19. dtlpy/assets/service_runners/multi_method_dataset.py +55 -55
  20. dtlpy/assets/service_runners/multi_method_item.py +52 -52
  21. dtlpy/assets/service_runners/multi_method_json.py +52 -52
  22. dtlpy/assets/service_runners/single_method.py +37 -37
  23. dtlpy/assets/service_runners/single_method_annotation.py +43 -43
  24. dtlpy/assets/service_runners/single_method_dataset.py +43 -43
  25. dtlpy/assets/service_runners/single_method_item.py +41 -41
  26. dtlpy/assets/service_runners/single_method_json.py +42 -42
  27. dtlpy/assets/service_runners/single_method_multi_input.py +45 -45
  28. dtlpy/assets/voc_annotation_template.xml +23 -23
  29. dtlpy/caches/base_cache.py +32 -32
  30. dtlpy/caches/cache.py +473 -473
  31. dtlpy/caches/dl_cache.py +201 -201
  32. dtlpy/caches/filesystem_cache.py +89 -89
  33. dtlpy/caches/redis_cache.py +84 -84
  34. dtlpy/dlp/__init__.py +20 -20
  35. dtlpy/dlp/cli_utilities.py +367 -367
  36. dtlpy/dlp/command_executor.py +764 -764
  37. dtlpy/dlp/dlp +1 -1
  38. dtlpy/dlp/dlp.bat +1 -1
  39. dtlpy/dlp/dlp.py +128 -128
  40. dtlpy/dlp/parser.py +651 -651
  41. dtlpy/entities/__init__.py +83 -83
  42. dtlpy/entities/analytic.py +347 -347
  43. dtlpy/entities/annotation.py +1879 -1879
  44. dtlpy/entities/annotation_collection.py +699 -699
  45. dtlpy/entities/annotation_definitions/__init__.py +20 -20
  46. dtlpy/entities/annotation_definitions/base_annotation_definition.py +100 -100
  47. dtlpy/entities/annotation_definitions/box.py +195 -195
  48. dtlpy/entities/annotation_definitions/classification.py +67 -67
  49. dtlpy/entities/annotation_definitions/comparison.py +72 -72
  50. dtlpy/entities/annotation_definitions/cube.py +204 -204
  51. dtlpy/entities/annotation_definitions/cube_3d.py +149 -149
  52. dtlpy/entities/annotation_definitions/description.py +32 -32
  53. dtlpy/entities/annotation_definitions/ellipse.py +124 -124
  54. dtlpy/entities/annotation_definitions/free_text.py +62 -62
  55. dtlpy/entities/annotation_definitions/gis.py +69 -69
  56. dtlpy/entities/annotation_definitions/note.py +139 -139
  57. dtlpy/entities/annotation_definitions/point.py +117 -117
  58. dtlpy/entities/annotation_definitions/polygon.py +182 -182
  59. dtlpy/entities/annotation_definitions/polyline.py +111 -111
  60. dtlpy/entities/annotation_definitions/pose.py +92 -92
  61. dtlpy/entities/annotation_definitions/ref_image.py +86 -86
  62. dtlpy/entities/annotation_definitions/segmentation.py +240 -240
  63. dtlpy/entities/annotation_definitions/subtitle.py +34 -34
  64. dtlpy/entities/annotation_definitions/text.py +85 -85
  65. dtlpy/entities/annotation_definitions/undefined_annotation.py +74 -74
  66. dtlpy/entities/app.py +220 -220
  67. dtlpy/entities/app_module.py +107 -107
  68. dtlpy/entities/artifact.py +174 -174
  69. dtlpy/entities/assignment.py +399 -399
  70. dtlpy/entities/base_entity.py +214 -214
  71. dtlpy/entities/bot.py +113 -113
  72. dtlpy/entities/codebase.py +292 -292
  73. dtlpy/entities/collection.py +38 -38
  74. dtlpy/entities/command.py +169 -169
  75. dtlpy/entities/compute.py +449 -449
  76. dtlpy/entities/dataset.py +1299 -1299
  77. dtlpy/entities/directory_tree.py +44 -44
  78. dtlpy/entities/dpk.py +470 -470
  79. dtlpy/entities/driver.py +235 -235
  80. dtlpy/entities/execution.py +397 -397
  81. dtlpy/entities/feature.py +124 -124
  82. dtlpy/entities/feature_set.py +152 -145
  83. dtlpy/entities/filters.py +798 -798
  84. dtlpy/entities/gis_item.py +107 -107
  85. dtlpy/entities/integration.py +184 -184
  86. dtlpy/entities/item.py +975 -959
  87. dtlpy/entities/label.py +123 -123
  88. dtlpy/entities/links.py +85 -85
  89. dtlpy/entities/message.py +175 -175
  90. dtlpy/entities/model.py +684 -684
  91. dtlpy/entities/node.py +1005 -1005
  92. dtlpy/entities/ontology.py +810 -803
  93. dtlpy/entities/organization.py +287 -287
  94. dtlpy/entities/package.py +657 -657
  95. dtlpy/entities/package_defaults.py +5 -5
  96. dtlpy/entities/package_function.py +185 -185
  97. dtlpy/entities/package_module.py +113 -113
  98. dtlpy/entities/package_slot.py +118 -118
  99. dtlpy/entities/paged_entities.py +299 -299
  100. dtlpy/entities/pipeline.py +624 -624
  101. dtlpy/entities/pipeline_execution.py +279 -279
  102. dtlpy/entities/project.py +394 -394
  103. dtlpy/entities/prompt_item.py +505 -505
  104. dtlpy/entities/recipe.py +301 -301
  105. dtlpy/entities/reflect_dict.py +102 -102
  106. dtlpy/entities/resource_execution.py +138 -138
  107. dtlpy/entities/service.py +974 -963
  108. dtlpy/entities/service_driver.py +117 -117
  109. dtlpy/entities/setting.py +294 -294
  110. dtlpy/entities/task.py +495 -495
  111. dtlpy/entities/time_series.py +143 -143
  112. dtlpy/entities/trigger.py +426 -426
  113. dtlpy/entities/user.py +118 -118
  114. dtlpy/entities/webhook.py +124 -124
  115. dtlpy/examples/__init__.py +19 -19
  116. dtlpy/examples/add_labels.py +135 -135
  117. dtlpy/examples/add_metadata_to_item.py +21 -21
  118. dtlpy/examples/annotate_items_using_model.py +65 -65
  119. dtlpy/examples/annotate_video_using_model_and_tracker.py +75 -75
  120. dtlpy/examples/annotations_convert_to_voc.py +9 -9
  121. dtlpy/examples/annotations_convert_to_yolo.py +9 -9
  122. dtlpy/examples/convert_annotation_types.py +51 -51
  123. dtlpy/examples/converter.py +143 -143
  124. dtlpy/examples/copy_annotations.py +22 -22
  125. dtlpy/examples/copy_folder.py +31 -31
  126. dtlpy/examples/create_annotations.py +51 -51
  127. dtlpy/examples/create_video_annotations.py +83 -83
  128. dtlpy/examples/delete_annotations.py +26 -26
  129. dtlpy/examples/filters.py +113 -113
  130. dtlpy/examples/move_item.py +23 -23
  131. dtlpy/examples/play_video_annotation.py +13 -13
  132. dtlpy/examples/show_item_and_mask.py +53 -53
  133. dtlpy/examples/triggers.py +49 -49
  134. dtlpy/examples/upload_batch_of_items.py +20 -20
  135. dtlpy/examples/upload_items_and_custom_format_annotations.py +55 -55
  136. dtlpy/examples/upload_items_with_modalities.py +43 -43
  137. dtlpy/examples/upload_segmentation_annotations_from_mask_image.py +44 -44
  138. dtlpy/examples/upload_yolo_format_annotations.py +70 -70
  139. dtlpy/exceptions.py +125 -125
  140. dtlpy/miscellaneous/__init__.py +20 -20
  141. dtlpy/miscellaneous/dict_differ.py +95 -95
  142. dtlpy/miscellaneous/git_utils.py +217 -217
  143. dtlpy/miscellaneous/json_utils.py +14 -14
  144. dtlpy/miscellaneous/list_print.py +105 -105
  145. dtlpy/miscellaneous/zipping.py +130 -130
  146. dtlpy/ml/__init__.py +20 -20
  147. dtlpy/ml/base_feature_extractor_adapter.py +27 -27
  148. dtlpy/ml/base_model_adapter.py +1287 -1230
  149. dtlpy/ml/metrics.py +461 -461
  150. dtlpy/ml/predictions_utils.py +274 -274
  151. dtlpy/ml/summary_writer.py +57 -57
  152. dtlpy/ml/train_utils.py +60 -60
  153. dtlpy/new_instance.py +252 -252
  154. dtlpy/repositories/__init__.py +56 -56
  155. dtlpy/repositories/analytics.py +85 -85
  156. dtlpy/repositories/annotations.py +916 -916
  157. dtlpy/repositories/apps.py +383 -383
  158. dtlpy/repositories/artifacts.py +452 -452
  159. dtlpy/repositories/assignments.py +599 -599
  160. dtlpy/repositories/bots.py +213 -213
  161. dtlpy/repositories/codebases.py +559 -559
  162. dtlpy/repositories/collections.py +332 -332
  163. dtlpy/repositories/commands.py +152 -152
  164. dtlpy/repositories/compositions.py +61 -61
  165. dtlpy/repositories/computes.py +439 -439
  166. dtlpy/repositories/datasets.py +1585 -1504
  167. dtlpy/repositories/downloader.py +1157 -923
  168. dtlpy/repositories/dpks.py +433 -433
  169. dtlpy/repositories/drivers.py +482 -482
  170. dtlpy/repositories/executions.py +815 -815
  171. dtlpy/repositories/feature_sets.py +256 -226
  172. dtlpy/repositories/features.py +255 -255
  173. dtlpy/repositories/integrations.py +484 -484
  174. dtlpy/repositories/items.py +912 -912
  175. dtlpy/repositories/messages.py +94 -94
  176. dtlpy/repositories/models.py +1000 -1000
  177. dtlpy/repositories/nodes.py +80 -80
  178. dtlpy/repositories/ontologies.py +511 -511
  179. dtlpy/repositories/organizations.py +525 -525
  180. dtlpy/repositories/packages.py +1941 -1941
  181. dtlpy/repositories/pipeline_executions.py +451 -451
  182. dtlpy/repositories/pipelines.py +640 -640
  183. dtlpy/repositories/projects.py +539 -539
  184. dtlpy/repositories/recipes.py +429 -399
  185. dtlpy/repositories/resource_executions.py +137 -137
  186. dtlpy/repositories/schema.py +120 -120
  187. dtlpy/repositories/service_drivers.py +213 -213
  188. dtlpy/repositories/services.py +1704 -1704
  189. dtlpy/repositories/settings.py +339 -339
  190. dtlpy/repositories/tasks.py +1477 -1477
  191. dtlpy/repositories/times_series.py +278 -278
  192. dtlpy/repositories/triggers.py +536 -536
  193. dtlpy/repositories/upload_element.py +257 -257
  194. dtlpy/repositories/uploader.py +661 -661
  195. dtlpy/repositories/webhooks.py +249 -249
  196. dtlpy/services/__init__.py +22 -22
  197. dtlpy/services/aihttp_retry.py +131 -131
  198. dtlpy/services/api_client.py +1786 -1785
  199. dtlpy/services/api_reference.py +40 -40
  200. dtlpy/services/async_utils.py +133 -133
  201. dtlpy/services/calls_counter.py +44 -44
  202. dtlpy/services/check_sdk.py +68 -68
  203. dtlpy/services/cookie.py +115 -115
  204. dtlpy/services/create_logger.py +156 -156
  205. dtlpy/services/events.py +84 -84
  206. dtlpy/services/logins.py +235 -235
  207. dtlpy/services/reporter.py +256 -256
  208. dtlpy/services/service_defaults.py +91 -91
  209. dtlpy/utilities/__init__.py +20 -20
  210. dtlpy/utilities/annotations/__init__.py +16 -16
  211. dtlpy/utilities/annotations/annotation_converters.py +269 -269
  212. dtlpy/utilities/base_package_runner.py +285 -264
  213. dtlpy/utilities/converter.py +1650 -1650
  214. dtlpy/utilities/dataset_generators/__init__.py +1 -1
  215. dtlpy/utilities/dataset_generators/dataset_generator.py +670 -670
  216. dtlpy/utilities/dataset_generators/dataset_generator_tensorflow.py +23 -23
  217. dtlpy/utilities/dataset_generators/dataset_generator_torch.py +21 -21
  218. dtlpy/utilities/local_development/__init__.py +1 -1
  219. dtlpy/utilities/local_development/local_session.py +179 -179
  220. dtlpy/utilities/reports/__init__.py +2 -2
  221. dtlpy/utilities/reports/figures.py +343 -343
  222. dtlpy/utilities/reports/report.py +71 -71
  223. dtlpy/utilities/videos/__init__.py +17 -17
  224. dtlpy/utilities/videos/video_player.py +598 -598
  225. dtlpy/utilities/videos/videos.py +470 -470
  226. {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp +1 -1
  227. dtlpy-1.117.6.data/scripts/dlp.bat +2 -0
  228. {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp.py +128 -128
  229. {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/METADATA +186 -186
  230. dtlpy-1.117.6.dist-info/RECORD +239 -0
  231. {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/WHEEL +1 -1
  232. {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/licenses/LICENSE +200 -200
  233. tests/features/environment.py +551 -551
  234. dtlpy/assets/__pycache__/__init__.cpython-310.pyc +0 -0
  235. dtlpy-1.115.44.data/scripts/dlp.bat +0 -2
  236. dtlpy-1.115.44.dist-info/RECORD +0 -240
  237. {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/entry_points.txt +0 -0
  238. {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/top_level.txt +0 -0
@@ -1,264 +1,285 @@
1
- import datetime
2
- import threading
3
-
4
- from .. import entities
5
-
6
-
7
- class BaseServiceRunner:
8
- _do_reset = False
9
- _auto_refresh_dtlpy_token = None
10
- _refresh_dtlpy_token = None
11
- _threads_terminated = list()
12
- _threads_terminated_lock = threading.Lock()
13
- _service_entity = None
14
-
15
- def do_reset(self):
16
- self._do_reset = True
17
-
18
- @staticmethod
19
- def ping(progress):
20
- progress.logger.debug('received ping at: {}'.format(datetime.datetime.now().isoformat()))
21
- return 'pong'
22
-
23
- def _terminate(self, tid):
24
- with self._threads_terminated_lock:
25
- self._threads_terminated.append(tid)
26
-
27
- def kill_event(self):
28
- ident = threading.get_ident()
29
- if ident in self._threads_terminated:
30
- with self._threads_terminated_lock:
31
- self._threads_terminated.pop(self._threads_terminated.index(ident))
32
- raise InterruptedError('Execution received termination signal')
33
-
34
- @property
35
- def service_entity(self) -> entities.Service:
36
- assert isinstance(self._service_entity, entities.Service), "service_entity must be a dl.Service object"
37
- return self._service_entity
38
-
39
- @service_entity.setter
40
- def service_entity(self, value):
41
- assert isinstance(value, entities.Service), "service_entity must be a dl.Service object"
42
- self._service_entity = value
43
-
44
-
45
- class Progress:
46
- """
47
- Follow the event progress
48
- """
49
-
50
- def update(self,
51
- status=None,
52
- progress=0,
53
- message=None,
54
- output=None,
55
- duration=None,
56
- action=None
57
- ):
58
- """
59
- Update the progress flow
60
-
61
- :param str status: the progress status to display
62
- :param int progress: number of finished flow
63
- :param str message: the progress message to display
64
- :param dict output: json serializable object to update the event output
65
- :param float duration: the event duration
66
- :param str action: event action
67
- """
68
- pass
69
-
70
-
71
- class ItemStatusEvent:
72
- def __init__(self, _json: dict):
73
- if _json is None:
74
- _json = dict()
75
-
76
- self.pipeline_id = _json.get('pipelineId', None)
77
- self.node_id = _json.get('nodeId', None)
78
- self.action = _json.get('action', None)
79
-
80
- status = _json.get('status', dict())
81
- if status is None:
82
- status = dict()
83
-
84
- self.task_id = status.get('taskId', None)
85
- self.assignment_id = status.get('assignmentId', None)
86
- self.status = status.get('status', None)
87
- self.creator = status.get('creator', None)
88
- self.timestamp = status.get('timestamp', None)
89
-
90
-
91
- class ExecutionEventContext:
92
- def __init__(self, _json: dict):
93
- if _json is None:
94
- _json = dict()
95
-
96
- self.resource = _json.get('resource', None)
97
- self.source = _json.get('source', None)
98
- self.action = _json.get('action', None)
99
- self.resource_id = _json.get('resourceId', None)
100
- self.user_id = _json.get('userId', None)
101
- self.dataset_id = _json.get('datasetId', None)
102
- self.project_id = _json.get('projectId', None)
103
- self.body = _json.get('body', None)
104
- self.item_status_event = ItemStatusEvent(_json.get('itemStatusEvent', dict()))
105
-
106
-
107
- class Context:
108
- """
109
- Contex of the service state
110
- """
111
-
112
- def __init__(
113
- self,
114
- service: entities.Service = None,
115
- package: entities.Package = None,
116
- project: entities.Project = None,
117
- event_context: dict = None,
118
- execution_dict: dict = None,
119
- progress: Progress = None,
120
- logger=None,
121
- sdk=None
122
- ):
123
- """
124
- A Context entity use DTLPY entities for context in a service runner
125
-
126
-
127
- :param dict execution_dict: the current execution dict in the state
128
- :param dict service: the current service entity in th state
129
- :param dict package: the current package entity in th state
130
- :param dict project: the current project entity in th state
131
- :param dict event_context: ExecutionEventContext json display the Execution event context
132
- :param dl.Progress progress: Progress object for work flow
133
- :param logger: logger object
134
- :param sdk: the dtlpy package
135
- """
136
- # dtlpy
137
- self._logger = logger
138
- self._sdk = sdk
139
- self._progress = progress
140
-
141
- self.event = ExecutionEventContext(event_context)
142
- if execution_dict is None:
143
- execution_dict = dict()
144
- self.execution_dict = execution_dict
145
-
146
- # ids
147
- self.trigger_id = execution_dict.get('trigger_id', None)
148
- self.execution_id = execution_dict.get('id', None)
149
-
150
- # pipeline
151
- pipeline = execution_dict.get('pipeline', dict())
152
- if pipeline is None:
153
- pipeline = dict()
154
- self.pipeline_id = pipeline.get('id', None)
155
- self.node_id = pipeline.get('nodeId', None)
156
- self.pipeline_execution_id = pipeline.get('executionId', None)
157
-
158
- # objects
159
- self._service = service
160
- self._package = package
161
- self._project = project
162
- self._task = None
163
- self._assignment = None
164
- self._pipeline = None
165
- self._node = None
166
- self._execution = None
167
- self._pipeline_execution = None
168
-
169
- @property
170
- def package(self):
171
- assert isinstance(self._package, entities.Package), "Missing `package` in context"
172
- return self._package
173
-
174
- @property
175
- def project(self):
176
- assert isinstance(self._project, entities.Project), "Missing `project` in context"
177
- return self._project
178
-
179
- @property
180
- def service(self):
181
- assert isinstance(self._service, entities.Service), "Missing `service` in context"
182
- return self._service
183
-
184
- @property
185
- def item_status_creator(self):
186
- return self.event.item_status_event.creator
187
-
188
- @property
189
- def item_status(self):
190
- return self.event.item_status_event.status
191
-
192
- @property
193
- def item_status_operation(self):
194
- return self.event.item_status_event.action
195
-
196
- @property
197
- def execution(self) -> entities.Execution:
198
- if self._execution is None:
199
- # noinspection PyProtectedMember
200
- self._execution = self.sdk.Execution.from_json(
201
- _json=self.execution_dict,
202
- client_api=self.service._client_api,
203
- service=self.service,
204
- project=self.project
205
- )
206
- return self._execution
207
-
208
- @property
209
- def task_id(self) -> str:
210
- return self.event.item_status_event.task_id
211
-
212
- @property
213
- def task(self) -> entities.Task:
214
- if self._task is None and self.task_id is not None:
215
- try:
216
- self._task = self.sdk.tasks.get(task_id=self.task_id)
217
- except Exception:
218
- self.logger.exception('Failed to get task')
219
- return self._task
220
-
221
- @property
222
- def assignment_id(self) -> str:
223
- return self.event.item_status_event.assignment_id
224
-
225
- @property
226
- def assignment(self) -> entities.Assignment:
227
- if self._assignment is None and self.assignment_id is not None:
228
- self._assignment = self.sdk.assignments.get(assignment_id=self.assignment_id)
229
- return self._assignment
230
-
231
- @property
232
- def pipeline(self) -> entities.Pipeline:
233
- if self._pipeline is None and self.pipeline_id is not None:
234
- self._pipeline = self.sdk.pipelines.get(pipeline_id=self.pipeline_id)
235
- return self._pipeline
236
-
237
- @property
238
- def node(self):
239
- if self._node is None and self.pipeline is not None and self.node_id is not None:
240
- self._node = [n for n in self.pipeline.nodes if n.node_id == self.node_id][0]
241
- return self._node
242
-
243
- @property
244
- def pipeline_execution(self):
245
- if self._pipeline_execution is None and self.pipeline_execution_id is not None:
246
- self._pipeline_execution = self.sdk.pipeline_executions.get(
247
- pipeline_execution_id=self.pipeline_execution_id,
248
- pipeline_id=self.pipeline_id
249
- )
250
- return self._pipeline_execution
251
-
252
- @property
253
- def sdk(self):
254
- if self._sdk is None:
255
- import dtlpy
256
- self._sdk = dtlpy
257
- return self._sdk
258
-
259
- @property
260
- def logger(self):
261
- if self._logger is None:
262
- import logging
263
- self._logger = logging.getLogger("[AgentContext]")
264
- return self._logger
1
+ import datetime
2
+ import threading
3
+
4
+ from .. import entities
5
+
6
+
7
+ class BaseServiceRunner:
8
+ _do_reset = False
9
+ _auto_refresh_dtlpy_token = None
10
+ _refresh_dtlpy_token = None
11
+ _threads_terminated = list()
12
+ _threads_terminated_lock = threading.Lock()
13
+ _service_entity = None
14
+
15
+ def do_reset(self):
16
+ self._do_reset = True
17
+
18
+ @staticmethod
19
+ def ping(progress):
20
+ progress.logger.debug('received ping at: {}'.format(datetime.datetime.now().isoformat()))
21
+ return 'pong'
22
+
23
+ def _terminate(self, tid):
24
+ with self._threads_terminated_lock:
25
+ self._threads_terminated.append(tid)
26
+
27
+ def kill_event(self):
28
+ ident = threading.get_ident()
29
+ if ident in self._threads_terminated:
30
+ with self._threads_terminated_lock:
31
+ self._threads_terminated.pop(self._threads_terminated.index(ident))
32
+ raise InterruptedError('Execution received termination signal')
33
+
34
+ @property
35
+ def service_entity(self) -> entities.Service:
36
+ assert isinstance(self._service_entity, entities.Service), "service_entity must be a dl.Service object"
37
+ return self._service_entity
38
+
39
+ @service_entity.setter
40
+ def service_entity(self, value):
41
+ assert isinstance(value, entities.Service), "service_entity must be a dl.Service object"
42
+ self._service_entity = value
43
+
44
+
45
+ class Progress:
46
+ """
47
+ Follow the event progress
48
+ """
49
+
50
+ def update(self,
51
+ status=None,
52
+ progress=0,
53
+ message=None,
54
+ output=None,
55
+ duration=None,
56
+ action=None
57
+ ):
58
+ """
59
+ Update the progress flow
60
+
61
+ :param str status: the progress status to display
62
+ :param int progress: number of finished flow
63
+ :param str message: the progress message to display
64
+ :param dict output: json serializable object to update the event output
65
+ :param float duration: the event duration
66
+ :param str action: event action
67
+ """
68
+ pass
69
+
70
+
71
+ class ItemStatusEvent:
72
+ def __init__(self, _json: dict):
73
+ if _json is None:
74
+ _json = dict()
75
+
76
+ self.pipeline_id = _json.get('pipelineId', None)
77
+ self.node_id = _json.get('nodeId', None)
78
+ self.action = _json.get('action', None)
79
+
80
+ status = _json.get('status', dict())
81
+ if status is None:
82
+ status = dict()
83
+
84
+ self.task_id = status.get('taskId', None)
85
+ self.assignment_id = status.get('assignmentId', None)
86
+ self.status = status.get('status', None)
87
+ self.creator = status.get('creator', None)
88
+ self.timestamp = status.get('timestamp', None)
89
+
90
+
91
+ class ExecutionEventContext:
92
+ def __init__(self, _json: dict):
93
+ if _json is None:
94
+ _json = dict()
95
+
96
+ self.resource = _json.get('resource', None)
97
+ self.source = _json.get('source', None)
98
+ self.action = _json.get('action', None)
99
+ self.resource_id = _json.get('resourceId', None)
100
+ self.user_id = _json.get('userId', None)
101
+ self.dataset_id = _json.get('datasetId', None)
102
+ self.project_id = _json.get('projectId', None)
103
+ self.body = _json.get('body', None)
104
+ self.item_status_event = ItemStatusEvent(_json.get('itemStatusEvent', dict()))
105
+
106
+
107
+ @property
108
+ def command_data(self):
109
+ if self.body is not None:
110
+ return self.body.get('commandData', None)
111
+ return None
112
+
113
+ @property
114
+ def command_id(self):
115
+ if self.command_data is not None:
116
+ return self.command_data.get('commandId', None)
117
+ return None
118
+
119
+
120
+ class Context:
121
+ """
122
+ Contex of the service state
123
+ """
124
+
125
+ def __init__(
126
+ self,
127
+ service: entities.Service = None,
128
+ package: entities.Package = None,
129
+ project: entities.Project = None,
130
+ event_context: dict = None,
131
+ execution_dict: dict = None,
132
+ progress: Progress = None,
133
+ logger=None,
134
+ sdk=None
135
+ ):
136
+ """
137
+ A Context entity use DTLPY entities for context in a service runner
138
+
139
+
140
+ :param dict execution_dict: the current execution dict in the state
141
+ :param dict service: the current service entity in th state
142
+ :param dict package: the current package entity in th state
143
+ :param dict project: the current project entity in th state
144
+ :param dict event_context: ExecutionEventContext json display the Execution event context
145
+ :param dl.Progress progress: Progress object for work flow
146
+ :param logger: logger object
147
+ :param sdk: the dtlpy package
148
+ """
149
+ # dtlpy
150
+ self._logger = logger
151
+ self._sdk = sdk
152
+ self._progress = progress
153
+
154
+ self.event = ExecutionEventContext(event_context)
155
+ if execution_dict is None:
156
+ execution_dict = dict()
157
+ self.execution_dict = execution_dict
158
+
159
+ # ids
160
+ self.trigger_id = execution_dict.get('trigger_id', None)
161
+ self.execution_id = execution_dict.get('id', None)
162
+
163
+ # pipeline
164
+ pipeline = execution_dict.get('pipeline', dict())
165
+ if pipeline is None:
166
+ pipeline = dict()
167
+ self.pipeline_id = pipeline.get('id', None)
168
+ self.node_id = pipeline.get('nodeId', None)
169
+ self.pipeline_execution_id = pipeline.get('executionId', None)
170
+
171
+ # objects
172
+ self._service = service
173
+ self._package = package
174
+ self._project = project
175
+ self._task = None
176
+ self._assignment = None
177
+ self._pipeline = None
178
+ self._node = None
179
+ self._execution = None
180
+ self._pipeline_execution = None
181
+
182
+ @property
183
+ def command_id(self):
184
+ return self.event.command_id
185
+
186
+ @property
187
+ def command_data(self):
188
+ return self.event.command_data
189
+
190
+ @property
191
+ def package(self):
192
+ assert isinstance(self._package, entities.Package), "Missing `package` in context"
193
+ return self._package
194
+
195
+ @property
196
+ def project(self):
197
+ assert isinstance(self._project, entities.Project), "Missing `project` in context"
198
+ return self._project
199
+
200
+ @property
201
+ def service(self):
202
+ assert isinstance(self._service, entities.Service), "Missing `service` in context"
203
+ return self._service
204
+
205
+ @property
206
+ def item_status_creator(self):
207
+ return self.event.item_status_event.creator
208
+
209
+ @property
210
+ def item_status(self):
211
+ return self.event.item_status_event.status
212
+
213
+ @property
214
+ def item_status_operation(self):
215
+ return self.event.item_status_event.action
216
+
217
+ @property
218
+ def execution(self) -> entities.Execution:
219
+ if self._execution is None:
220
+ # noinspection PyProtectedMember
221
+ self._execution = self.sdk.Execution.from_json(
222
+ _json=self.execution_dict,
223
+ client_api=self.service._client_api,
224
+ service=self.service,
225
+ project=self.project
226
+ )
227
+ return self._execution
228
+
229
+ @property
230
+ def task_id(self) -> str:
231
+ return self.event.item_status_event.task_id
232
+
233
+ @property
234
+ def task(self) -> entities.Task:
235
+ if self._task is None and self.task_id is not None:
236
+ try:
237
+ self._task = self.sdk.tasks.get(task_id=self.task_id)
238
+ except Exception:
239
+ self.logger.exception('Failed to get task')
240
+ return self._task
241
+
242
+ @property
243
+ def assignment_id(self) -> str:
244
+ return self.event.item_status_event.assignment_id
245
+
246
+ @property
247
+ def assignment(self) -> entities.Assignment:
248
+ if self._assignment is None and self.assignment_id is not None:
249
+ self._assignment = self.sdk.assignments.get(assignment_id=self.assignment_id)
250
+ return self._assignment
251
+
252
+ @property
253
+ def pipeline(self) -> entities.Pipeline:
254
+ if self._pipeline is None and self.pipeline_id is not None:
255
+ self._pipeline = self.sdk.pipelines.get(pipeline_id=self.pipeline_id)
256
+ return self._pipeline
257
+
258
+ @property
259
+ def node(self):
260
+ if self._node is None and self.pipeline is not None and self.node_id is not None:
261
+ self._node = [n for n in self.pipeline.nodes if n.node_id == self.node_id][0]
262
+ return self._node
263
+
264
+ @property
265
+ def pipeline_execution(self):
266
+ if self._pipeline_execution is None and self.pipeline_execution_id is not None:
267
+ self._pipeline_execution = self.sdk.pipeline_executions.get(
268
+ pipeline_execution_id=self.pipeline_execution_id,
269
+ pipeline_id=self.pipeline_id
270
+ )
271
+ return self._pipeline_execution
272
+
273
+ @property
274
+ def sdk(self):
275
+ if self._sdk is None:
276
+ import dtlpy
277
+ self._sdk = dtlpy
278
+ return self._sdk
279
+
280
+ @property
281
+ def logger(self):
282
+ if self._logger is None:
283
+ import logging
284
+ self._logger = logging.getLogger("[AgentContext]")
285
+ return self._logger