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.
- dtlpy/__init__.py +491 -491
- dtlpy/__version__.py +1 -1
- dtlpy/assets/__init__.py +26 -26
- dtlpy/assets/code_server/config.yaml +2 -2
- dtlpy/assets/code_server/installation.sh +24 -24
- dtlpy/assets/code_server/launch.json +13 -13
- dtlpy/assets/code_server/settings.json +2 -2
- dtlpy/assets/main.py +53 -53
- dtlpy/assets/main_partial.py +18 -18
- dtlpy/assets/mock.json +11 -11
- dtlpy/assets/model_adapter.py +83 -83
- dtlpy/assets/package.json +61 -61
- dtlpy/assets/package_catalog.json +29 -29
- dtlpy/assets/package_gitignore +307 -307
- dtlpy/assets/service_runners/__init__.py +33 -33
- dtlpy/assets/service_runners/converter.py +96 -96
- dtlpy/assets/service_runners/multi_method.py +49 -49
- dtlpy/assets/service_runners/multi_method_annotation.py +54 -54
- dtlpy/assets/service_runners/multi_method_dataset.py +55 -55
- dtlpy/assets/service_runners/multi_method_item.py +52 -52
- dtlpy/assets/service_runners/multi_method_json.py +52 -52
- dtlpy/assets/service_runners/single_method.py +37 -37
- dtlpy/assets/service_runners/single_method_annotation.py +43 -43
- dtlpy/assets/service_runners/single_method_dataset.py +43 -43
- dtlpy/assets/service_runners/single_method_item.py +41 -41
- dtlpy/assets/service_runners/single_method_json.py +42 -42
- dtlpy/assets/service_runners/single_method_multi_input.py +45 -45
- dtlpy/assets/voc_annotation_template.xml +23 -23
- dtlpy/caches/base_cache.py +32 -32
- dtlpy/caches/cache.py +473 -473
- dtlpy/caches/dl_cache.py +201 -201
- dtlpy/caches/filesystem_cache.py +89 -89
- dtlpy/caches/redis_cache.py +84 -84
- dtlpy/dlp/__init__.py +20 -20
- dtlpy/dlp/cli_utilities.py +367 -367
- dtlpy/dlp/command_executor.py +764 -764
- dtlpy/dlp/dlp +1 -1
- dtlpy/dlp/dlp.bat +1 -1
- dtlpy/dlp/dlp.py +128 -128
- dtlpy/dlp/parser.py +651 -651
- dtlpy/entities/__init__.py +83 -83
- dtlpy/entities/analytic.py +347 -347
- dtlpy/entities/annotation.py +1879 -1879
- dtlpy/entities/annotation_collection.py +699 -699
- dtlpy/entities/annotation_definitions/__init__.py +20 -20
- dtlpy/entities/annotation_definitions/base_annotation_definition.py +100 -100
- dtlpy/entities/annotation_definitions/box.py +195 -195
- dtlpy/entities/annotation_definitions/classification.py +67 -67
- dtlpy/entities/annotation_definitions/comparison.py +72 -72
- dtlpy/entities/annotation_definitions/cube.py +204 -204
- dtlpy/entities/annotation_definitions/cube_3d.py +149 -149
- dtlpy/entities/annotation_definitions/description.py +32 -32
- dtlpy/entities/annotation_definitions/ellipse.py +124 -124
- dtlpy/entities/annotation_definitions/free_text.py +62 -62
- dtlpy/entities/annotation_definitions/gis.py +69 -69
- dtlpy/entities/annotation_definitions/note.py +139 -139
- dtlpy/entities/annotation_definitions/point.py +117 -117
- dtlpy/entities/annotation_definitions/polygon.py +182 -182
- dtlpy/entities/annotation_definitions/polyline.py +111 -111
- dtlpy/entities/annotation_definitions/pose.py +92 -92
- dtlpy/entities/annotation_definitions/ref_image.py +86 -86
- dtlpy/entities/annotation_definitions/segmentation.py +240 -240
- dtlpy/entities/annotation_definitions/subtitle.py +34 -34
- dtlpy/entities/annotation_definitions/text.py +85 -85
- dtlpy/entities/annotation_definitions/undefined_annotation.py +74 -74
- dtlpy/entities/app.py +220 -220
- dtlpy/entities/app_module.py +107 -107
- dtlpy/entities/artifact.py +174 -174
- dtlpy/entities/assignment.py +399 -399
- dtlpy/entities/base_entity.py +214 -214
- dtlpy/entities/bot.py +113 -113
- dtlpy/entities/codebase.py +292 -292
- dtlpy/entities/collection.py +38 -38
- dtlpy/entities/command.py +169 -169
- dtlpy/entities/compute.py +449 -449
- dtlpy/entities/dataset.py +1299 -1299
- dtlpy/entities/directory_tree.py +44 -44
- dtlpy/entities/dpk.py +470 -470
- dtlpy/entities/driver.py +235 -235
- dtlpy/entities/execution.py +397 -397
- dtlpy/entities/feature.py +124 -124
- dtlpy/entities/feature_set.py +152 -145
- dtlpy/entities/filters.py +798 -798
- dtlpy/entities/gis_item.py +107 -107
- dtlpy/entities/integration.py +184 -184
- dtlpy/entities/item.py +975 -959
- dtlpy/entities/label.py +123 -123
- dtlpy/entities/links.py +85 -85
- dtlpy/entities/message.py +175 -175
- dtlpy/entities/model.py +684 -684
- dtlpy/entities/node.py +1005 -1005
- dtlpy/entities/ontology.py +810 -803
- dtlpy/entities/organization.py +287 -287
- dtlpy/entities/package.py +657 -657
- dtlpy/entities/package_defaults.py +5 -5
- dtlpy/entities/package_function.py +185 -185
- dtlpy/entities/package_module.py +113 -113
- dtlpy/entities/package_slot.py +118 -118
- dtlpy/entities/paged_entities.py +299 -299
- dtlpy/entities/pipeline.py +624 -624
- dtlpy/entities/pipeline_execution.py +279 -279
- dtlpy/entities/project.py +394 -394
- dtlpy/entities/prompt_item.py +505 -505
- dtlpy/entities/recipe.py +301 -301
- dtlpy/entities/reflect_dict.py +102 -102
- dtlpy/entities/resource_execution.py +138 -138
- dtlpy/entities/service.py +974 -963
- dtlpy/entities/service_driver.py +117 -117
- dtlpy/entities/setting.py +294 -294
- dtlpy/entities/task.py +495 -495
- dtlpy/entities/time_series.py +143 -143
- dtlpy/entities/trigger.py +426 -426
- dtlpy/entities/user.py +118 -118
- dtlpy/entities/webhook.py +124 -124
- dtlpy/examples/__init__.py +19 -19
- dtlpy/examples/add_labels.py +135 -135
- dtlpy/examples/add_metadata_to_item.py +21 -21
- dtlpy/examples/annotate_items_using_model.py +65 -65
- dtlpy/examples/annotate_video_using_model_and_tracker.py +75 -75
- dtlpy/examples/annotations_convert_to_voc.py +9 -9
- dtlpy/examples/annotations_convert_to_yolo.py +9 -9
- dtlpy/examples/convert_annotation_types.py +51 -51
- dtlpy/examples/converter.py +143 -143
- dtlpy/examples/copy_annotations.py +22 -22
- dtlpy/examples/copy_folder.py +31 -31
- dtlpy/examples/create_annotations.py +51 -51
- dtlpy/examples/create_video_annotations.py +83 -83
- dtlpy/examples/delete_annotations.py +26 -26
- dtlpy/examples/filters.py +113 -113
- dtlpy/examples/move_item.py +23 -23
- dtlpy/examples/play_video_annotation.py +13 -13
- dtlpy/examples/show_item_and_mask.py +53 -53
- dtlpy/examples/triggers.py +49 -49
- dtlpy/examples/upload_batch_of_items.py +20 -20
- dtlpy/examples/upload_items_and_custom_format_annotations.py +55 -55
- dtlpy/examples/upload_items_with_modalities.py +43 -43
- dtlpy/examples/upload_segmentation_annotations_from_mask_image.py +44 -44
- dtlpy/examples/upload_yolo_format_annotations.py +70 -70
- dtlpy/exceptions.py +125 -125
- dtlpy/miscellaneous/__init__.py +20 -20
- dtlpy/miscellaneous/dict_differ.py +95 -95
- dtlpy/miscellaneous/git_utils.py +217 -217
- dtlpy/miscellaneous/json_utils.py +14 -14
- dtlpy/miscellaneous/list_print.py +105 -105
- dtlpy/miscellaneous/zipping.py +130 -130
- dtlpy/ml/__init__.py +20 -20
- dtlpy/ml/base_feature_extractor_adapter.py +27 -27
- dtlpy/ml/base_model_adapter.py +1287 -1230
- dtlpy/ml/metrics.py +461 -461
- dtlpy/ml/predictions_utils.py +274 -274
- dtlpy/ml/summary_writer.py +57 -57
- dtlpy/ml/train_utils.py +60 -60
- dtlpy/new_instance.py +252 -252
- dtlpy/repositories/__init__.py +56 -56
- dtlpy/repositories/analytics.py +85 -85
- dtlpy/repositories/annotations.py +916 -916
- dtlpy/repositories/apps.py +383 -383
- dtlpy/repositories/artifacts.py +452 -452
- dtlpy/repositories/assignments.py +599 -599
- dtlpy/repositories/bots.py +213 -213
- dtlpy/repositories/codebases.py +559 -559
- dtlpy/repositories/collections.py +332 -332
- dtlpy/repositories/commands.py +152 -152
- dtlpy/repositories/compositions.py +61 -61
- dtlpy/repositories/computes.py +439 -439
- dtlpy/repositories/datasets.py +1585 -1504
- dtlpy/repositories/downloader.py +1157 -923
- dtlpy/repositories/dpks.py +433 -433
- dtlpy/repositories/drivers.py +482 -482
- dtlpy/repositories/executions.py +815 -815
- dtlpy/repositories/feature_sets.py +256 -226
- dtlpy/repositories/features.py +255 -255
- dtlpy/repositories/integrations.py +484 -484
- dtlpy/repositories/items.py +912 -912
- dtlpy/repositories/messages.py +94 -94
- dtlpy/repositories/models.py +1000 -1000
- dtlpy/repositories/nodes.py +80 -80
- dtlpy/repositories/ontologies.py +511 -511
- dtlpy/repositories/organizations.py +525 -525
- dtlpy/repositories/packages.py +1941 -1941
- dtlpy/repositories/pipeline_executions.py +451 -451
- dtlpy/repositories/pipelines.py +640 -640
- dtlpy/repositories/projects.py +539 -539
- dtlpy/repositories/recipes.py +429 -399
- dtlpy/repositories/resource_executions.py +137 -137
- dtlpy/repositories/schema.py +120 -120
- dtlpy/repositories/service_drivers.py +213 -213
- dtlpy/repositories/services.py +1704 -1704
- dtlpy/repositories/settings.py +339 -339
- dtlpy/repositories/tasks.py +1477 -1477
- dtlpy/repositories/times_series.py +278 -278
- dtlpy/repositories/triggers.py +536 -536
- dtlpy/repositories/upload_element.py +257 -257
- dtlpy/repositories/uploader.py +661 -661
- dtlpy/repositories/webhooks.py +249 -249
- dtlpy/services/__init__.py +22 -22
- dtlpy/services/aihttp_retry.py +131 -131
- dtlpy/services/api_client.py +1786 -1785
- dtlpy/services/api_reference.py +40 -40
- dtlpy/services/async_utils.py +133 -133
- dtlpy/services/calls_counter.py +44 -44
- dtlpy/services/check_sdk.py +68 -68
- dtlpy/services/cookie.py +115 -115
- dtlpy/services/create_logger.py +156 -156
- dtlpy/services/events.py +84 -84
- dtlpy/services/logins.py +235 -235
- dtlpy/services/reporter.py +256 -256
- dtlpy/services/service_defaults.py +91 -91
- dtlpy/utilities/__init__.py +20 -20
- dtlpy/utilities/annotations/__init__.py +16 -16
- dtlpy/utilities/annotations/annotation_converters.py +269 -269
- dtlpy/utilities/base_package_runner.py +285 -264
- dtlpy/utilities/converter.py +1650 -1650
- dtlpy/utilities/dataset_generators/__init__.py +1 -1
- dtlpy/utilities/dataset_generators/dataset_generator.py +670 -670
- dtlpy/utilities/dataset_generators/dataset_generator_tensorflow.py +23 -23
- dtlpy/utilities/dataset_generators/dataset_generator_torch.py +21 -21
- dtlpy/utilities/local_development/__init__.py +1 -1
- dtlpy/utilities/local_development/local_session.py +179 -179
- dtlpy/utilities/reports/__init__.py +2 -2
- dtlpy/utilities/reports/figures.py +343 -343
- dtlpy/utilities/reports/report.py +71 -71
- dtlpy/utilities/videos/__init__.py +17 -17
- dtlpy/utilities/videos/video_player.py +598 -598
- dtlpy/utilities/videos/videos.py +470 -470
- {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp +1 -1
- dtlpy-1.117.6.data/scripts/dlp.bat +2 -0
- {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp.py +128 -128
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/METADATA +186 -186
- dtlpy-1.117.6.dist-info/RECORD +239 -0
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/WHEEL +1 -1
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/licenses/LICENSE +200 -200
- tests/features/environment.py +551 -551
- dtlpy/assets/__pycache__/__init__.cpython-310.pyc +0 -0
- dtlpy-1.115.44.data/scripts/dlp.bat +0 -2
- dtlpy-1.115.44.dist-info/RECORD +0 -240
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/entry_points.txt +0 -0
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/top_level.txt +0 -0
dtlpy/repositories/commands.py
CHANGED
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import logging
|
|
3
|
-
import time
|
|
4
|
-
import tqdm
|
|
5
|
-
import sys
|
|
6
|
-
|
|
7
|
-
from .. import exceptions, entities, miscellaneous
|
|
8
|
-
from ..services.api_client import ApiClient
|
|
9
|
-
|
|
10
|
-
logger = logging.getLogger(name='dtlpy')
|
|
11
|
-
|
|
12
|
-
MAX_SLEEP_TIME = 30
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class Commands:
|
|
16
|
-
"""
|
|
17
|
-
Service Commands repository
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, client_api: ApiClient):
|
|
21
|
-
self._client_api = client_api
|
|
22
|
-
|
|
23
|
-
############
|
|
24
|
-
# entities #
|
|
25
|
-
############
|
|
26
|
-
|
|
27
|
-
def list(self):
|
|
28
|
-
"""
|
|
29
|
-
List of commands
|
|
30
|
-
|
|
31
|
-
:return: list of commands
|
|
32
|
-
"""
|
|
33
|
-
url = '/commands'
|
|
34
|
-
|
|
35
|
-
# request
|
|
36
|
-
success, response = self._client_api.gen_request(req_type='get',
|
|
37
|
-
path=url)
|
|
38
|
-
if not success:
|
|
39
|
-
raise exceptions.PlatformException(response)
|
|
40
|
-
|
|
41
|
-
commands = miscellaneous.List([entities.Command.from_json(_json=_json,
|
|
42
|
-
client_api=self._client_api) for _json in
|
|
43
|
-
response.json()])
|
|
44
|
-
return commands
|
|
45
|
-
|
|
46
|
-
def get(self,
|
|
47
|
-
command_id: str = None,
|
|
48
|
-
url: str = None
|
|
49
|
-
) -> entities.Command:
|
|
50
|
-
"""
|
|
51
|
-
Get Service command object
|
|
52
|
-
|
|
53
|
-
:param str command_id:
|
|
54
|
-
:param str url: command url
|
|
55
|
-
:return: Command object
|
|
56
|
-
"""
|
|
57
|
-
if url is None:
|
|
58
|
-
url_path = "/commands/{}".format(command_id)
|
|
59
|
-
else:
|
|
60
|
-
url_path = url.split('api/v1')[1]
|
|
61
|
-
|
|
62
|
-
success, response = self._client_api.gen_request(req_type="get",
|
|
63
|
-
path=url_path)
|
|
64
|
-
|
|
65
|
-
# exception handling
|
|
66
|
-
if not success:
|
|
67
|
-
raise exceptions.PlatformException(response)
|
|
68
|
-
|
|
69
|
-
# return entity
|
|
70
|
-
return entities.Command.from_json(client_api=self._client_api,
|
|
71
|
-
_json=response.json())
|
|
72
|
-
|
|
73
|
-
def wait(self, command_id, timeout=0, step=None, url=None, backoff_factor=1, iteration_callback=None):
|
|
74
|
-
"""
|
|
75
|
-
Wait for command to finish
|
|
76
|
-
|
|
77
|
-
backoff_factor: A backoff factor to apply between attempts after the second try
|
|
78
|
-
{backoff factor} * (2 ** ({number of total retries} - 1))
|
|
79
|
-
seconds. If the backoff_factor is 1, then :func:`.sleep` will sleep
|
|
80
|
-
for [0s, 2s, 4s, ...] between retries. It will never be longer
|
|
81
|
-
than 30 sec
|
|
82
|
-
|
|
83
|
-
:param str command_id: Command id to wait to
|
|
84
|
-
:param int timeout: int, seconds to wait until TimeoutError is raised. if 0 - wait until done
|
|
85
|
-
:param int step: int, seconds between polling
|
|
86
|
-
:param str url: url to the command
|
|
87
|
-
:param function iteration_callback: function to call on each iteration
|
|
88
|
-
:param float backoff_factor: A backoff factor to apply between attempts after the second try
|
|
89
|
-
:return: Command object
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
elapsed = 0
|
|
93
|
-
start = time.time()
|
|
94
|
-
if timeout is None or timeout <= 0:
|
|
95
|
-
timeout = np.inf
|
|
96
|
-
|
|
97
|
-
command = None
|
|
98
|
-
pbar = tqdm.tqdm(total=100,
|
|
99
|
-
disable=self._client_api.verbose.disable_progress_bar_command_progress,
|
|
100
|
-
file=sys.stdout,
|
|
101
|
-
desc='Command Progress')
|
|
102
|
-
num_tries = 1
|
|
103
|
-
while elapsed < timeout:
|
|
104
|
-
command = self.get(command_id=command_id, url=url)
|
|
105
|
-
if command.type == 'ExportDatasetAsJson':
|
|
106
|
-
self._client_api.callbacks.run_on_event(event=self._client_api.callbacks.CallbackEvent.DATASET_EXPORT,
|
|
107
|
-
context=command.spec,
|
|
108
|
-
progress=command.progress)
|
|
109
|
-
|
|
110
|
-
pbar.update(command.progress - pbar.n)
|
|
111
|
-
if not command.in_progress():
|
|
112
|
-
break
|
|
113
|
-
elapsed = time.time() - start
|
|
114
|
-
sleep_time = np.min([timeout - elapsed, backoff_factor * (2 ** num_tries), MAX_SLEEP_TIME])
|
|
115
|
-
num_tries += 1
|
|
116
|
-
logger.debug(f"Command {command.id} is running for {elapsed:.2f}[s]. Sleeping for {sleep_time:.2f}[s]")
|
|
117
|
-
if iteration_callback is not None:
|
|
118
|
-
try:
|
|
119
|
-
iteration_callback()
|
|
120
|
-
except Exception as e:
|
|
121
|
-
logger.warning('iteration_callback failed: {}'.format(e.__str__()))
|
|
122
|
-
time.sleep(sleep_time)
|
|
123
|
-
pbar.close()
|
|
124
|
-
if command is None:
|
|
125
|
-
raise ValueError('Nothing to wait for')
|
|
126
|
-
if elapsed >= timeout:
|
|
127
|
-
raise TimeoutError("command wait() got timeout. id: {!r}, status: {}, progress {}%".format(
|
|
128
|
-
command.id, command.status, command.progress))
|
|
129
|
-
if command.status != entities.CommandsStatus.SUCCESS:
|
|
130
|
-
raise exceptions.PlatformException(error='424',
|
|
131
|
-
message="Command {!r} {}: '{}'".format(command.id,
|
|
132
|
-
command.status,
|
|
133
|
-
command.error))
|
|
134
|
-
return command
|
|
135
|
-
|
|
136
|
-
def abort(self, command_id: str):
|
|
137
|
-
"""
|
|
138
|
-
Abort Command
|
|
139
|
-
|
|
140
|
-
:param str command_id: command id
|
|
141
|
-
:return:
|
|
142
|
-
"""
|
|
143
|
-
# request
|
|
144
|
-
success, response = self._client_api.gen_request(req_type='post',
|
|
145
|
-
path='/commands/{}/abort'.format(command_id))
|
|
146
|
-
|
|
147
|
-
# exception handling
|
|
148
|
-
if not success:
|
|
149
|
-
raise exceptions.PlatformException(response)
|
|
150
|
-
else:
|
|
151
|
-
return entities.Command.from_json(_json=response.json(),
|
|
152
|
-
client_api=self._client_api)
|
|
1
|
+
import numpy as np
|
|
2
|
+
import logging
|
|
3
|
+
import time
|
|
4
|
+
import tqdm
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from .. import exceptions, entities, miscellaneous
|
|
8
|
+
from ..services.api_client import ApiClient
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(name='dtlpy')
|
|
11
|
+
|
|
12
|
+
MAX_SLEEP_TIME = 30
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Commands:
|
|
16
|
+
"""
|
|
17
|
+
Service Commands repository
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, client_api: ApiClient):
|
|
21
|
+
self._client_api = client_api
|
|
22
|
+
|
|
23
|
+
############
|
|
24
|
+
# entities #
|
|
25
|
+
############
|
|
26
|
+
|
|
27
|
+
def list(self):
|
|
28
|
+
"""
|
|
29
|
+
List of commands
|
|
30
|
+
|
|
31
|
+
:return: list of commands
|
|
32
|
+
"""
|
|
33
|
+
url = '/commands'
|
|
34
|
+
|
|
35
|
+
# request
|
|
36
|
+
success, response = self._client_api.gen_request(req_type='get',
|
|
37
|
+
path=url)
|
|
38
|
+
if not success:
|
|
39
|
+
raise exceptions.PlatformException(response)
|
|
40
|
+
|
|
41
|
+
commands = miscellaneous.List([entities.Command.from_json(_json=_json,
|
|
42
|
+
client_api=self._client_api) for _json in
|
|
43
|
+
response.json()])
|
|
44
|
+
return commands
|
|
45
|
+
|
|
46
|
+
def get(self,
|
|
47
|
+
command_id: str = None,
|
|
48
|
+
url: str = None
|
|
49
|
+
) -> entities.Command:
|
|
50
|
+
"""
|
|
51
|
+
Get Service command object
|
|
52
|
+
|
|
53
|
+
:param str command_id:
|
|
54
|
+
:param str url: command url
|
|
55
|
+
:return: Command object
|
|
56
|
+
"""
|
|
57
|
+
if url is None:
|
|
58
|
+
url_path = "/commands/{}".format(command_id)
|
|
59
|
+
else:
|
|
60
|
+
url_path = url.split('api/v1')[1]
|
|
61
|
+
|
|
62
|
+
success, response = self._client_api.gen_request(req_type="get",
|
|
63
|
+
path=url_path)
|
|
64
|
+
|
|
65
|
+
# exception handling
|
|
66
|
+
if not success:
|
|
67
|
+
raise exceptions.PlatformException(response)
|
|
68
|
+
|
|
69
|
+
# return entity
|
|
70
|
+
return entities.Command.from_json(client_api=self._client_api,
|
|
71
|
+
_json=response.json())
|
|
72
|
+
|
|
73
|
+
def wait(self, command_id, timeout=0, step=None, url=None, backoff_factor=1, iteration_callback=None):
|
|
74
|
+
"""
|
|
75
|
+
Wait for command to finish
|
|
76
|
+
|
|
77
|
+
backoff_factor: A backoff factor to apply between attempts after the second try
|
|
78
|
+
{backoff factor} * (2 ** ({number of total retries} - 1))
|
|
79
|
+
seconds. If the backoff_factor is 1, then :func:`.sleep` will sleep
|
|
80
|
+
for [0s, 2s, 4s, ...] between retries. It will never be longer
|
|
81
|
+
than 30 sec
|
|
82
|
+
|
|
83
|
+
:param str command_id: Command id to wait to
|
|
84
|
+
:param int timeout: int, seconds to wait until TimeoutError is raised. if 0 - wait until done
|
|
85
|
+
:param int step: int, seconds between polling
|
|
86
|
+
:param str url: url to the command
|
|
87
|
+
:param function iteration_callback: function to call on each iteration
|
|
88
|
+
:param float backoff_factor: A backoff factor to apply between attempts after the second try
|
|
89
|
+
:return: Command object
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
elapsed = 0
|
|
93
|
+
start = time.time()
|
|
94
|
+
if timeout is None or timeout <= 0:
|
|
95
|
+
timeout = np.inf
|
|
96
|
+
|
|
97
|
+
command = None
|
|
98
|
+
pbar = tqdm.tqdm(total=100,
|
|
99
|
+
disable=self._client_api.verbose.disable_progress_bar_command_progress,
|
|
100
|
+
file=sys.stdout,
|
|
101
|
+
desc='Command Progress')
|
|
102
|
+
num_tries = 1
|
|
103
|
+
while elapsed < timeout:
|
|
104
|
+
command = self.get(command_id=command_id, url=url)
|
|
105
|
+
if command.type == 'ExportDatasetAsJson':
|
|
106
|
+
self._client_api.callbacks.run_on_event(event=self._client_api.callbacks.CallbackEvent.DATASET_EXPORT,
|
|
107
|
+
context=command.spec,
|
|
108
|
+
progress=command.progress)
|
|
109
|
+
|
|
110
|
+
pbar.update(command.progress - pbar.n)
|
|
111
|
+
if not command.in_progress():
|
|
112
|
+
break
|
|
113
|
+
elapsed = time.time() - start
|
|
114
|
+
sleep_time = np.min([timeout - elapsed, backoff_factor * (2 ** num_tries), MAX_SLEEP_TIME])
|
|
115
|
+
num_tries += 1
|
|
116
|
+
logger.debug(f"Command {command.id} is running for {elapsed:.2f}[s]. Sleeping for {sleep_time:.2f}[s]")
|
|
117
|
+
if iteration_callback is not None:
|
|
118
|
+
try:
|
|
119
|
+
iteration_callback()
|
|
120
|
+
except Exception as e:
|
|
121
|
+
logger.warning('iteration_callback failed: {}'.format(e.__str__()))
|
|
122
|
+
time.sleep(sleep_time)
|
|
123
|
+
pbar.close()
|
|
124
|
+
if command is None:
|
|
125
|
+
raise ValueError('Nothing to wait for')
|
|
126
|
+
if elapsed >= timeout:
|
|
127
|
+
raise TimeoutError("command wait() got timeout. id: {!r}, status: {}, progress {}%".format(
|
|
128
|
+
command.id, command.status, command.progress))
|
|
129
|
+
if command.status != entities.CommandsStatus.SUCCESS:
|
|
130
|
+
raise exceptions.PlatformException(error='424',
|
|
131
|
+
message="Command {!r} {}: '{}'".format(command.id,
|
|
132
|
+
command.status,
|
|
133
|
+
command.error))
|
|
134
|
+
return command
|
|
135
|
+
|
|
136
|
+
def abort(self, command_id: str):
|
|
137
|
+
"""
|
|
138
|
+
Abort Command
|
|
139
|
+
|
|
140
|
+
:param str command_id: command id
|
|
141
|
+
:return:
|
|
142
|
+
"""
|
|
143
|
+
# request
|
|
144
|
+
success, response = self._client_api.gen_request(req_type='post',
|
|
145
|
+
path='/commands/{}/abort'.format(command_id))
|
|
146
|
+
|
|
147
|
+
# exception handling
|
|
148
|
+
if not success:
|
|
149
|
+
raise exceptions.PlatformException(response)
|
|
150
|
+
else:
|
|
151
|
+
return entities.Command.from_json(_json=response.json(),
|
|
152
|
+
client_api=self._client_api)
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from .. import entities, repositories, exceptions, miscellaneous, _api_reference
|
|
3
|
-
from ..services.api_client import ApiClient
|
|
4
|
-
|
|
5
|
-
logger = logging.getLogger(name='dtlpy')
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Compositions:
|
|
9
|
-
def __init__(self, client_api: ApiClient, project: entities.Project = None):
|
|
10
|
-
self._client_api = client_api
|
|
11
|
-
self._project = project
|
|
12
|
-
|
|
13
|
-
############
|
|
14
|
-
# entities #
|
|
15
|
-
############
|
|
16
|
-
@property
|
|
17
|
-
def project(self) -> entities.Project:
|
|
18
|
-
if self._project is None:
|
|
19
|
-
try:
|
|
20
|
-
self._project = repositories.Projects(client_api=self._client_api).get()
|
|
21
|
-
except exceptions.NotFound:
|
|
22
|
-
raise exceptions.PlatformException(
|
|
23
|
-
error='2001',
|
|
24
|
-
message='Missing "project". need to set a Project entity or use project.pipelines repository')
|
|
25
|
-
return self._project
|
|
26
|
-
|
|
27
|
-
@project.setter
|
|
28
|
-
def project(self, project: entities.Project):
|
|
29
|
-
if not isinstance(project, entities.Project):
|
|
30
|
-
raise ValueError('Must input a valid Project entity')
|
|
31
|
-
self._project = project
|
|
32
|
-
|
|
33
|
-
def get(self,
|
|
34
|
-
composition_id=None,
|
|
35
|
-
fetch=None
|
|
36
|
-
) -> entities.Pipeline:
|
|
37
|
-
|
|
38
|
-
if fetch is None:
|
|
39
|
-
fetch = self._client_api.fetch_entities
|
|
40
|
-
|
|
41
|
-
if composition_id is None:
|
|
42
|
-
raise exceptions.PlatformException(
|
|
43
|
-
error='400',
|
|
44
|
-
message='Must provide an identifier in inputs')
|
|
45
|
-
|
|
46
|
-
elif fetch:
|
|
47
|
-
if composition_id is not None:
|
|
48
|
-
success, response = self._client_api.gen_request(
|
|
49
|
-
req_type="get",
|
|
50
|
-
path="/compositions/{}".format(composition_id))
|
|
51
|
-
if not success:
|
|
52
|
-
raise exceptions.PlatformException(response)
|
|
53
|
-
composition = response.json()
|
|
54
|
-
else:
|
|
55
|
-
raise exceptions.PlatformException(
|
|
56
|
-
error='400',
|
|
57
|
-
message='No checked-out pipeline was found, must checkout or provide an identifier in inputs')
|
|
58
|
-
else:
|
|
59
|
-
composition = {'id': composition_id}
|
|
60
|
-
|
|
61
|
-
return composition
|
|
1
|
+
import logging
|
|
2
|
+
from .. import entities, repositories, exceptions, miscellaneous, _api_reference
|
|
3
|
+
from ..services.api_client import ApiClient
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(name='dtlpy')
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Compositions:
|
|
9
|
+
def __init__(self, client_api: ApiClient, project: entities.Project = None):
|
|
10
|
+
self._client_api = client_api
|
|
11
|
+
self._project = project
|
|
12
|
+
|
|
13
|
+
############
|
|
14
|
+
# entities #
|
|
15
|
+
############
|
|
16
|
+
@property
|
|
17
|
+
def project(self) -> entities.Project:
|
|
18
|
+
if self._project is None:
|
|
19
|
+
try:
|
|
20
|
+
self._project = repositories.Projects(client_api=self._client_api).get()
|
|
21
|
+
except exceptions.NotFound:
|
|
22
|
+
raise exceptions.PlatformException(
|
|
23
|
+
error='2001',
|
|
24
|
+
message='Missing "project". need to set a Project entity or use project.pipelines repository')
|
|
25
|
+
return self._project
|
|
26
|
+
|
|
27
|
+
@project.setter
|
|
28
|
+
def project(self, project: entities.Project):
|
|
29
|
+
if not isinstance(project, entities.Project):
|
|
30
|
+
raise ValueError('Must input a valid Project entity')
|
|
31
|
+
self._project = project
|
|
32
|
+
|
|
33
|
+
def get(self,
|
|
34
|
+
composition_id=None,
|
|
35
|
+
fetch=None
|
|
36
|
+
) -> entities.Pipeline:
|
|
37
|
+
|
|
38
|
+
if fetch is None:
|
|
39
|
+
fetch = self._client_api.fetch_entities
|
|
40
|
+
|
|
41
|
+
if composition_id is None:
|
|
42
|
+
raise exceptions.PlatformException(
|
|
43
|
+
error='400',
|
|
44
|
+
message='Must provide an identifier in inputs')
|
|
45
|
+
|
|
46
|
+
elif fetch:
|
|
47
|
+
if composition_id is not None:
|
|
48
|
+
success, response = self._client_api.gen_request(
|
|
49
|
+
req_type="get",
|
|
50
|
+
path="/compositions/{}".format(composition_id))
|
|
51
|
+
if not success:
|
|
52
|
+
raise exceptions.PlatformException(response)
|
|
53
|
+
composition = response.json()
|
|
54
|
+
else:
|
|
55
|
+
raise exceptions.PlatformException(
|
|
56
|
+
error='400',
|
|
57
|
+
message='No checked-out pipeline was found, must checkout or provide an identifier in inputs')
|
|
58
|
+
else:
|
|
59
|
+
composition = {'id': composition_id}
|
|
60
|
+
|
|
61
|
+
return composition
|