dtlpy 1.113.10__py3-none-any.whl → 1.114.13__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 +488 -488
- dtlpy/__version__.py +1 -1
- dtlpy/assets/__init__.py +26 -26
- dtlpy/assets/__pycache__/__init__.cpython-38.pyc +0 -0
- 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 +311 -311
- 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 +296 -296
- dtlpy/entities/collection.py +38 -38
- dtlpy/entities/command.py +169 -169
- dtlpy/entities/compute.py +442 -442
- dtlpy/entities/dataset.py +1285 -1285
- dtlpy/entities/directory_tree.py +44 -44
- dtlpy/entities/dpk.py +470 -470
- dtlpy/entities/driver.py +222 -222
- dtlpy/entities/execution.py +397 -397
- dtlpy/entities/feature.py +124 -124
- dtlpy/entities/feature_set.py +145 -145
- dtlpy/entities/filters.py +641 -641
- dtlpy/entities/gis_item.py +107 -107
- dtlpy/entities/integration.py +184 -184
- dtlpy/entities/item.py +953 -953
- dtlpy/entities/label.py +123 -123
- dtlpy/entities/links.py +85 -85
- dtlpy/entities/message.py +175 -175
- dtlpy/entities/model.py +694 -691
- dtlpy/entities/node.py +1005 -1005
- dtlpy/entities/ontology.py +803 -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 +290 -267
- dtlpy/entities/pipeline.py +593 -593
- dtlpy/entities/pipeline_execution.py +279 -279
- dtlpy/entities/project.py +394 -394
- dtlpy/entities/prompt_item.py +499 -499
- dtlpy/entities/recipe.py +301 -301
- dtlpy/entities/reflect_dict.py +102 -102
- dtlpy/entities/resource_execution.py +138 -138
- dtlpy/entities/service.py +958 -958
- dtlpy/entities/service_driver.py +117 -117
- dtlpy/entities/setting.py +294 -294
- dtlpy/entities/task.py +491 -491
- 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 +945 -940
- 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 -348
- dtlpy/repositories/commands.py +158 -158
- dtlpy/repositories/compositions.py +61 -61
- dtlpy/repositories/computes.py +434 -406
- dtlpy/repositories/datasets.py +1291 -1291
- dtlpy/repositories/downloader.py +895 -895
- dtlpy/repositories/dpks.py +433 -433
- dtlpy/repositories/drivers.py +266 -266
- dtlpy/repositories/executions.py +817 -817
- dtlpy/repositories/feature_sets.py +226 -226
- dtlpy/repositories/features.py +238 -238
- dtlpy/repositories/integrations.py +484 -484
- dtlpy/repositories/items.py +909 -915
- dtlpy/repositories/messages.py +94 -94
- dtlpy/repositories/models.py +877 -867
- 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 +448 -448
- dtlpy/repositories/pipelines.py +642 -642
- dtlpy/repositories/projects.py +539 -539
- dtlpy/repositories/recipes.py +399 -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 +1124 -1124
- dtlpy/repositories/times_series.py +278 -278
- dtlpy/repositories/triggers.py +536 -536
- dtlpy/repositories/upload_element.py +257 -257
- dtlpy/repositories/uploader.py +651 -651
- dtlpy/repositories/webhooks.py +249 -249
- dtlpy/services/__init__.py +22 -22
- dtlpy/services/aihttp_retry.py +131 -131
- dtlpy/services/api_client.py +1782 -1782
- 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 +264 -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.113.10.data → dtlpy-1.114.13.data}/scripts/dlp +1 -1
- dtlpy-1.114.13.data/scripts/dlp.bat +2 -0
- {dtlpy-1.113.10.data → dtlpy-1.114.13.data}/scripts/dlp.py +128 -128
- {dtlpy-1.113.10.dist-info → dtlpy-1.114.13.dist-info}/LICENSE +200 -200
- {dtlpy-1.113.10.dist-info → dtlpy-1.114.13.dist-info}/METADATA +172 -172
- dtlpy-1.114.13.dist-info/RECORD +240 -0
- {dtlpy-1.113.10.dist-info → dtlpy-1.114.13.dist-info}/WHEEL +1 -1
- tests/features/environment.py +551 -550
- dtlpy-1.113.10.data/scripts/dlp.bat +0 -2
- dtlpy-1.113.10.dist-info/RECORD +0 -244
- tests/assets/__init__.py +0 -0
- tests/assets/models_flow/__init__.py +0 -0
- tests/assets/models_flow/failedmain.py +0 -52
- tests/assets/models_flow/main.py +0 -62
- tests/assets/models_flow/main_model.py +0 -54
- {dtlpy-1.113.10.dist-info → dtlpy-1.114.13.dist-info}/entry_points.txt +0 -0
- {dtlpy-1.113.10.dist-info → dtlpy-1.114.13.dist-info}/top_level.txt +0 -0
dtlpy/repositories/features.py
CHANGED
|
@@ -1,238 +1,238 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
from .. import exceptions, entities, miscellaneous, _api_reference, repositories
|
|
4
|
-
from ..services.api_client import ApiClient
|
|
5
|
-
|
|
6
|
-
logger = logging.getLogger(name='dtlpy')
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Features:
|
|
10
|
-
"""
|
|
11
|
-
Features repository
|
|
12
|
-
"""
|
|
13
|
-
URL = '/features/vectors'
|
|
14
|
-
|
|
15
|
-
def __init__(self, client_api: ApiClient,
|
|
16
|
-
project: entities.Project = None,
|
|
17
|
-
project_id: str = None,
|
|
18
|
-
item: entities.Item = None,
|
|
19
|
-
annotation: entities.Annotation = None,
|
|
20
|
-
feature_set: entities.FeatureSet = None,
|
|
21
|
-
dataset: entities.Dataset = None):
|
|
22
|
-
if project is not None and project_id is None:
|
|
23
|
-
project_id = project.id
|
|
24
|
-
self._dataset = dataset
|
|
25
|
-
self._project = project
|
|
26
|
-
self._project_id = project_id
|
|
27
|
-
self._item = item
|
|
28
|
-
self._annotation = annotation
|
|
29
|
-
self._feature_set = feature_set
|
|
30
|
-
self._client_api = client_api
|
|
31
|
-
|
|
32
|
-
############
|
|
33
|
-
# entities #
|
|
34
|
-
############
|
|
35
|
-
@property
|
|
36
|
-
def feature_set(self) -> entities.FeatureSet:
|
|
37
|
-
return self._feature_set
|
|
38
|
-
|
|
39
|
-
@property
|
|
40
|
-
def project(self) -> entities.Project:
|
|
41
|
-
if self._project is None and self._project_id is None and self._item is not None:
|
|
42
|
-
self._project = self._item.project
|
|
43
|
-
self._project_id = self._project.id
|
|
44
|
-
if self._project is None and self._project_id is not None:
|
|
45
|
-
# get from id
|
|
46
|
-
self._project = repositories.Projects(client_api=self._client_api).get(project_id=self._project_id)
|
|
47
|
-
if self._project is None:
|
|
48
|
-
# try get checkout
|
|
49
|
-
project = self._client_api.state_io.get('project')
|
|
50
|
-
if project is not None:
|
|
51
|
-
self._project = entities.Project.from_json(_json=project, client_api=self._client_api)
|
|
52
|
-
if self._project is None:
|
|
53
|
-
raise exceptions.PlatformException(
|
|
54
|
-
error='2001',
|
|
55
|
-
message='Cannot perform action WITHOUT Project entity in Features repository.'
|
|
56
|
-
' Please checkout or set a project')
|
|
57
|
-
assert isinstance(self._project, entities.Project)
|
|
58
|
-
return self._project
|
|
59
|
-
|
|
60
|
-
###########
|
|
61
|
-
# methods #
|
|
62
|
-
###########
|
|
63
|
-
def _list(self, filters: entities.Filters):
|
|
64
|
-
"""
|
|
65
|
-
Get dataset feature vectors list. This is a browsing endpoint, for any given path feature count will be returned,
|
|
66
|
-
user is expected to perform another request then for every folder item to actually get the item list.
|
|
67
|
-
|
|
68
|
-
:param dtlpy.entities.filters.Filters filters: Filters entity or a dictionary containing filters parameters
|
|
69
|
-
:return: json response
|
|
70
|
-
"""
|
|
71
|
-
# prepare request
|
|
72
|
-
success, response = self._client_api.gen_request(req_type="POST",
|
|
73
|
-
path="{}/query".format(self.URL),
|
|
74
|
-
json_req=filters.prepare(),
|
|
75
|
-
headers={'user_query': filters._user_query}
|
|
76
|
-
)
|
|
77
|
-
if not success:
|
|
78
|
-
raise exceptions.PlatformException(response)
|
|
79
|
-
return response.json()
|
|
80
|
-
|
|
81
|
-
@_api_reference.add(path='/features/vectors', method='post')
|
|
82
|
-
def list(self, filters: entities.Filters = None) -> entities.PagedEntities:
|
|
83
|
-
"""
|
|
84
|
-
List of features
|
|
85
|
-
|
|
86
|
-
:param dtlpy.entities.filters.Filters filters: Filters to query the features data
|
|
87
|
-
:return: Pages object
|
|
88
|
-
:rtype: dtlpy.entities.paged_entities.PagedEntities
|
|
89
|
-
"""
|
|
90
|
-
# default filters
|
|
91
|
-
if filters is None:
|
|
92
|
-
filters = entities.Filters(resource=entities.FiltersResource.FEATURE)
|
|
93
|
-
filters._user_query = 'false'
|
|
94
|
-
# default sorting
|
|
95
|
-
if filters.sort == dict():
|
|
96
|
-
filters.sort_by(field='id')
|
|
97
|
-
# assert type filters
|
|
98
|
-
if not isinstance(filters, entities.Filters):
|
|
99
|
-
raise exceptions.PlatformException(error='400',
|
|
100
|
-
message='Unknown filters type: {!r}'.format(type(filters)))
|
|
101
|
-
if filters.resource != entities.FiltersResource.FEATURE:
|
|
102
|
-
raise exceptions.PlatformException(
|
|
103
|
-
error='400',
|
|
104
|
-
message='Filters resource must to be FiltersResource.FEATURE. Got: {!r}'.format(filters.resource))
|
|
105
|
-
if self._feature_set is not None:
|
|
106
|
-
filters.add(field='featureSetId', values=self._feature_set.id)
|
|
107
|
-
if self._item is not None:
|
|
108
|
-
filters.add(field='entityId', values=self._item.id)
|
|
109
|
-
if self._dataset is not None:
|
|
110
|
-
filters.add(field='datasetId', values=self._dataset.id)
|
|
111
|
-
if self._project_id is None:
|
|
112
|
-
self._project_id = self.project.id
|
|
113
|
-
filters.context = {"projects": [self._project_id]}
|
|
114
|
-
|
|
115
|
-
paged = entities.PagedEntities(items_repository=self,
|
|
116
|
-
filters=filters,
|
|
117
|
-
page_offset=filters.page,
|
|
118
|
-
page_size=filters.page_size,
|
|
119
|
-
client_api=self._client_api)
|
|
120
|
-
paged.get_page()
|
|
121
|
-
return paged
|
|
122
|
-
|
|
123
|
-
@_api_reference.add(path='/features/vectors/{id}', method='get')
|
|
124
|
-
def get(self, feature_id: str) -> entities.Feature:
|
|
125
|
-
"""
|
|
126
|
-
Get Feature object
|
|
127
|
-
|
|
128
|
-
:param str feature_id: feature id
|
|
129
|
-
:return: Feature object
|
|
130
|
-
"""
|
|
131
|
-
|
|
132
|
-
success, response = self._client_api.gen_request(req_type="GET",
|
|
133
|
-
path="{}/{}".format(self.URL, feature_id))
|
|
134
|
-
|
|
135
|
-
# exception handling
|
|
136
|
-
if not success:
|
|
137
|
-
raise exceptions.PlatformException(response)
|
|
138
|
-
|
|
139
|
-
# return entity
|
|
140
|
-
return entities.Feature.from_json(client_api=self._client_api,
|
|
141
|
-
_json=response.json())
|
|
142
|
-
|
|
143
|
-
@_api_reference.add(path='/features/vectors', method='post')
|
|
144
|
-
def create(self,
|
|
145
|
-
value,
|
|
146
|
-
project_id: str = None,
|
|
147
|
-
feature_set_id: str = None,
|
|
148
|
-
entity=None,
|
|
149
|
-
version: str = None,
|
|
150
|
-
parent_id: str = None,
|
|
151
|
-
org_id: str = None
|
|
152
|
-
):
|
|
153
|
-
"""
|
|
154
|
-
Create a new Feature vector
|
|
155
|
-
|
|
156
|
-
:param immutable value: actual vector - immutable (list of floats [1,2,3])
|
|
157
|
-
:param str project_id: the id of the project where feature will be created
|
|
158
|
-
:param str feature_set_id: ref to a featureSet this vector is a part of
|
|
159
|
-
:param entity: the entity the featureVector is linked to (item, annotation, etc)
|
|
160
|
-
:param str version: version of the featureSet generator
|
|
161
|
-
:param str parent_id: optional: parent FeatureSet id - used when FeatureVector is a subFeature
|
|
162
|
-
:param str org_id: the id of the org where featureVector will be created
|
|
163
|
-
:return: Feature vector:
|
|
164
|
-
"""
|
|
165
|
-
if project_id is None:
|
|
166
|
-
if self._project is not None:
|
|
167
|
-
project_id = self._project.id
|
|
168
|
-
elif self._project_id is not None:
|
|
169
|
-
project_id = self._project_id
|
|
170
|
-
else:
|
|
171
|
-
raise ValueError('Must insert a project id')
|
|
172
|
-
|
|
173
|
-
if feature_set_id is None:
|
|
174
|
-
if self._feature_set is None:
|
|
175
|
-
raise ValueError(
|
|
176
|
-
'Missing feature_set_id. Must insert the variable or create from context, e.g. feature_set.features.create()')
|
|
177
|
-
feature_set_id = self._feature_set.id
|
|
178
|
-
|
|
179
|
-
payload = {'project': project_id,
|
|
180
|
-
'entityId': entity.id,
|
|
181
|
-
'value': value,
|
|
182
|
-
'featureSetId': feature_set_id,
|
|
183
|
-
'datasetId': entity.dataset.id}
|
|
184
|
-
|
|
185
|
-
if version is not None:
|
|
186
|
-
payload['version'] = version
|
|
187
|
-
if parent_id is not None:
|
|
188
|
-
payload['parentId'] = parent_id
|
|
189
|
-
if org_id is not None:
|
|
190
|
-
payload['org'] = org_id
|
|
191
|
-
|
|
192
|
-
success, response = self._client_api.gen_request(req_type="post",
|
|
193
|
-
json_req=payload,
|
|
194
|
-
path=self.URL)
|
|
195
|
-
|
|
196
|
-
# exception handling
|
|
197
|
-
if not success:
|
|
198
|
-
raise exceptions.PlatformException(response)
|
|
199
|
-
|
|
200
|
-
# return entity
|
|
201
|
-
return entities.Feature.from_json(client_api=self._client_api,
|
|
202
|
-
_json=response.json()[0])
|
|
203
|
-
|
|
204
|
-
@_api_reference.add(path='/features/vectors/{id}', method='delete')
|
|
205
|
-
def delete(self, feature_id: str):
|
|
206
|
-
"""
|
|
207
|
-
Delete feature vector
|
|
208
|
-
|
|
209
|
-
:param str feature_id: feature id to delete
|
|
210
|
-
:return: success
|
|
211
|
-
:rtype: bool
|
|
212
|
-
"""
|
|
213
|
-
|
|
214
|
-
success, response = self._client_api.gen_request(req_type="delete",
|
|
215
|
-
path="{}/{}".format(self.URL, feature_id))
|
|
216
|
-
|
|
217
|
-
# check response
|
|
218
|
-
if success:
|
|
219
|
-
logger.debug("Feature deleted successfully")
|
|
220
|
-
return success
|
|
221
|
-
else:
|
|
222
|
-
raise exceptions.PlatformException(response)
|
|
223
|
-
|
|
224
|
-
def _build_entities_from_response(self, response_items) -> miscellaneous.List[entities.Item]:
|
|
225
|
-
pool = self._client_api.thread_pools(pool_name='entity.create')
|
|
226
|
-
jobs = [None for _ in range(len(response_items))]
|
|
227
|
-
# return triggers list
|
|
228
|
-
for i_item, item in enumerate(response_items):
|
|
229
|
-
jobs[i_item] = pool.submit(entities.Feature._protected_from_json,
|
|
230
|
-
**{'client_api': self._client_api,
|
|
231
|
-
'_json': item})
|
|
232
|
-
# get all results
|
|
233
|
-
results = [j.result() for j in jobs]
|
|
234
|
-
# log errors
|
|
235
|
-
_ = [logger.warning(r[1]) for r in results if r[0] is False]
|
|
236
|
-
# return good jobs
|
|
237
|
-
items = miscellaneous.List([r[1] for r in results if r[0] is True])
|
|
238
|
-
return items
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from .. import exceptions, entities, miscellaneous, _api_reference, repositories
|
|
4
|
+
from ..services.api_client import ApiClient
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(name='dtlpy')
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Features:
|
|
10
|
+
"""
|
|
11
|
+
Features repository
|
|
12
|
+
"""
|
|
13
|
+
URL = '/features/vectors'
|
|
14
|
+
|
|
15
|
+
def __init__(self, client_api: ApiClient,
|
|
16
|
+
project: entities.Project = None,
|
|
17
|
+
project_id: str = None,
|
|
18
|
+
item: entities.Item = None,
|
|
19
|
+
annotation: entities.Annotation = None,
|
|
20
|
+
feature_set: entities.FeatureSet = None,
|
|
21
|
+
dataset: entities.Dataset = None):
|
|
22
|
+
if project is not None and project_id is None:
|
|
23
|
+
project_id = project.id
|
|
24
|
+
self._dataset = dataset
|
|
25
|
+
self._project = project
|
|
26
|
+
self._project_id = project_id
|
|
27
|
+
self._item = item
|
|
28
|
+
self._annotation = annotation
|
|
29
|
+
self._feature_set = feature_set
|
|
30
|
+
self._client_api = client_api
|
|
31
|
+
|
|
32
|
+
############
|
|
33
|
+
# entities #
|
|
34
|
+
############
|
|
35
|
+
@property
|
|
36
|
+
def feature_set(self) -> entities.FeatureSet:
|
|
37
|
+
return self._feature_set
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def project(self) -> entities.Project:
|
|
41
|
+
if self._project is None and self._project_id is None and self._item is not None:
|
|
42
|
+
self._project = self._item.project
|
|
43
|
+
self._project_id = self._project.id
|
|
44
|
+
if self._project is None and self._project_id is not None:
|
|
45
|
+
# get from id
|
|
46
|
+
self._project = repositories.Projects(client_api=self._client_api).get(project_id=self._project_id)
|
|
47
|
+
if self._project is None:
|
|
48
|
+
# try get checkout
|
|
49
|
+
project = self._client_api.state_io.get('project')
|
|
50
|
+
if project is not None:
|
|
51
|
+
self._project = entities.Project.from_json(_json=project, client_api=self._client_api)
|
|
52
|
+
if self._project is None:
|
|
53
|
+
raise exceptions.PlatformException(
|
|
54
|
+
error='2001',
|
|
55
|
+
message='Cannot perform action WITHOUT Project entity in Features repository.'
|
|
56
|
+
' Please checkout or set a project')
|
|
57
|
+
assert isinstance(self._project, entities.Project)
|
|
58
|
+
return self._project
|
|
59
|
+
|
|
60
|
+
###########
|
|
61
|
+
# methods #
|
|
62
|
+
###########
|
|
63
|
+
def _list(self, filters: entities.Filters):
|
|
64
|
+
"""
|
|
65
|
+
Get dataset feature vectors list. This is a browsing endpoint, for any given path feature count will be returned,
|
|
66
|
+
user is expected to perform another request then for every folder item to actually get the item list.
|
|
67
|
+
|
|
68
|
+
:param dtlpy.entities.filters.Filters filters: Filters entity or a dictionary containing filters parameters
|
|
69
|
+
:return: json response
|
|
70
|
+
"""
|
|
71
|
+
# prepare request
|
|
72
|
+
success, response = self._client_api.gen_request(req_type="POST",
|
|
73
|
+
path="{}/query".format(self.URL),
|
|
74
|
+
json_req=filters.prepare(),
|
|
75
|
+
headers={'user_query': filters._user_query}
|
|
76
|
+
)
|
|
77
|
+
if not success:
|
|
78
|
+
raise exceptions.PlatformException(response)
|
|
79
|
+
return response.json()
|
|
80
|
+
|
|
81
|
+
@_api_reference.add(path='/features/vectors', method='post')
|
|
82
|
+
def list(self, filters: entities.Filters = None) -> entities.PagedEntities:
|
|
83
|
+
"""
|
|
84
|
+
List of features
|
|
85
|
+
|
|
86
|
+
:param dtlpy.entities.filters.Filters filters: Filters to query the features data
|
|
87
|
+
:return: Pages object
|
|
88
|
+
:rtype: dtlpy.entities.paged_entities.PagedEntities
|
|
89
|
+
"""
|
|
90
|
+
# default filters
|
|
91
|
+
if filters is None:
|
|
92
|
+
filters = entities.Filters(resource=entities.FiltersResource.FEATURE)
|
|
93
|
+
filters._user_query = 'false'
|
|
94
|
+
# default sorting
|
|
95
|
+
if filters.sort == dict():
|
|
96
|
+
filters.sort_by(field='id')
|
|
97
|
+
# assert type filters
|
|
98
|
+
if not isinstance(filters, entities.Filters):
|
|
99
|
+
raise exceptions.PlatformException(error='400',
|
|
100
|
+
message='Unknown filters type: {!r}'.format(type(filters)))
|
|
101
|
+
if filters.resource != entities.FiltersResource.FEATURE:
|
|
102
|
+
raise exceptions.PlatformException(
|
|
103
|
+
error='400',
|
|
104
|
+
message='Filters resource must to be FiltersResource.FEATURE. Got: {!r}'.format(filters.resource))
|
|
105
|
+
if self._feature_set is not None:
|
|
106
|
+
filters.add(field='featureSetId', values=self._feature_set.id)
|
|
107
|
+
if self._item is not None:
|
|
108
|
+
filters.add(field='entityId', values=self._item.id)
|
|
109
|
+
if self._dataset is not None:
|
|
110
|
+
filters.add(field='datasetId', values=self._dataset.id)
|
|
111
|
+
if self._project_id is None:
|
|
112
|
+
self._project_id = self.project.id
|
|
113
|
+
filters.context = {"projects": [self._project_id]}
|
|
114
|
+
|
|
115
|
+
paged = entities.PagedEntities(items_repository=self,
|
|
116
|
+
filters=filters,
|
|
117
|
+
page_offset=filters.page,
|
|
118
|
+
page_size=filters.page_size,
|
|
119
|
+
client_api=self._client_api)
|
|
120
|
+
paged.get_page()
|
|
121
|
+
return paged
|
|
122
|
+
|
|
123
|
+
@_api_reference.add(path='/features/vectors/{id}', method='get')
|
|
124
|
+
def get(self, feature_id: str) -> entities.Feature:
|
|
125
|
+
"""
|
|
126
|
+
Get Feature object
|
|
127
|
+
|
|
128
|
+
:param str feature_id: feature id
|
|
129
|
+
:return: Feature object
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
success, response = self._client_api.gen_request(req_type="GET",
|
|
133
|
+
path="{}/{}".format(self.URL, feature_id))
|
|
134
|
+
|
|
135
|
+
# exception handling
|
|
136
|
+
if not success:
|
|
137
|
+
raise exceptions.PlatformException(response)
|
|
138
|
+
|
|
139
|
+
# return entity
|
|
140
|
+
return entities.Feature.from_json(client_api=self._client_api,
|
|
141
|
+
_json=response.json())
|
|
142
|
+
|
|
143
|
+
@_api_reference.add(path='/features/vectors', method='post')
|
|
144
|
+
def create(self,
|
|
145
|
+
value,
|
|
146
|
+
project_id: str = None,
|
|
147
|
+
feature_set_id: str = None,
|
|
148
|
+
entity=None,
|
|
149
|
+
version: str = None,
|
|
150
|
+
parent_id: str = None,
|
|
151
|
+
org_id: str = None
|
|
152
|
+
):
|
|
153
|
+
"""
|
|
154
|
+
Create a new Feature vector
|
|
155
|
+
|
|
156
|
+
:param immutable value: actual vector - immutable (list of floats [1,2,3])
|
|
157
|
+
:param str project_id: the id of the project where feature will be created
|
|
158
|
+
:param str feature_set_id: ref to a featureSet this vector is a part of
|
|
159
|
+
:param entity: the entity the featureVector is linked to (item, annotation, etc)
|
|
160
|
+
:param str version: version of the featureSet generator
|
|
161
|
+
:param str parent_id: optional: parent FeatureSet id - used when FeatureVector is a subFeature
|
|
162
|
+
:param str org_id: the id of the org where featureVector will be created
|
|
163
|
+
:return: Feature vector:
|
|
164
|
+
"""
|
|
165
|
+
if project_id is None:
|
|
166
|
+
if self._project is not None:
|
|
167
|
+
project_id = self._project.id
|
|
168
|
+
elif self._project_id is not None:
|
|
169
|
+
project_id = self._project_id
|
|
170
|
+
else:
|
|
171
|
+
raise ValueError('Must insert a project id')
|
|
172
|
+
|
|
173
|
+
if feature_set_id is None:
|
|
174
|
+
if self._feature_set is None:
|
|
175
|
+
raise ValueError(
|
|
176
|
+
'Missing feature_set_id. Must insert the variable or create from context, e.g. feature_set.features.create()')
|
|
177
|
+
feature_set_id = self._feature_set.id
|
|
178
|
+
|
|
179
|
+
payload = {'project': project_id,
|
|
180
|
+
'entityId': entity.id,
|
|
181
|
+
'value': value,
|
|
182
|
+
'featureSetId': feature_set_id,
|
|
183
|
+
'datasetId': entity.dataset.id}
|
|
184
|
+
|
|
185
|
+
if version is not None:
|
|
186
|
+
payload['version'] = version
|
|
187
|
+
if parent_id is not None:
|
|
188
|
+
payload['parentId'] = parent_id
|
|
189
|
+
if org_id is not None:
|
|
190
|
+
payload['org'] = org_id
|
|
191
|
+
|
|
192
|
+
success, response = self._client_api.gen_request(req_type="post",
|
|
193
|
+
json_req=payload,
|
|
194
|
+
path=self.URL)
|
|
195
|
+
|
|
196
|
+
# exception handling
|
|
197
|
+
if not success:
|
|
198
|
+
raise exceptions.PlatformException(response)
|
|
199
|
+
|
|
200
|
+
# return entity
|
|
201
|
+
return entities.Feature.from_json(client_api=self._client_api,
|
|
202
|
+
_json=response.json()[0])
|
|
203
|
+
|
|
204
|
+
@_api_reference.add(path='/features/vectors/{id}', method='delete')
|
|
205
|
+
def delete(self, feature_id: str):
|
|
206
|
+
"""
|
|
207
|
+
Delete feature vector
|
|
208
|
+
|
|
209
|
+
:param str feature_id: feature id to delete
|
|
210
|
+
:return: success
|
|
211
|
+
:rtype: bool
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
success, response = self._client_api.gen_request(req_type="delete",
|
|
215
|
+
path="{}/{}".format(self.URL, feature_id))
|
|
216
|
+
|
|
217
|
+
# check response
|
|
218
|
+
if success:
|
|
219
|
+
logger.debug("Feature deleted successfully")
|
|
220
|
+
return success
|
|
221
|
+
else:
|
|
222
|
+
raise exceptions.PlatformException(response)
|
|
223
|
+
|
|
224
|
+
def _build_entities_from_response(self, response_items) -> miscellaneous.List[entities.Item]:
|
|
225
|
+
pool = self._client_api.thread_pools(pool_name='entity.create')
|
|
226
|
+
jobs = [None for _ in range(len(response_items))]
|
|
227
|
+
# return triggers list
|
|
228
|
+
for i_item, item in enumerate(response_items):
|
|
229
|
+
jobs[i_item] = pool.submit(entities.Feature._protected_from_json,
|
|
230
|
+
**{'client_api': self._client_api,
|
|
231
|
+
'_json': item})
|
|
232
|
+
# get all results
|
|
233
|
+
results = [j.result() for j in jobs]
|
|
234
|
+
# log errors
|
|
235
|
+
_ = [logger.warning(r[1]) for r in results if r[0] is False]
|
|
236
|
+
# return good jobs
|
|
237
|
+
items = miscellaneous.List([r[1] for r in results if r[0] is True])
|
|
238
|
+
return items
|