superb-ai-onprem 0.1.6__py3-none-any.whl → 0.3.0__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.
Potentially problematic release.
This version of superb-ai-onprem might be problematic. Click here for more details.
- spb_onprem/__init__.py +26 -3
- spb_onprem/_version.py +2 -2
- spb_onprem/activities/__init__.py +0 -0
- spb_onprem/activities/entities/__init__.py +10 -0
- spb_onprem/activities/entities/activity.py +39 -0
- spb_onprem/activities/entities/activity_history.py +31 -0
- spb_onprem/activities/params/__init__.py +23 -0
- spb_onprem/activities/params/activities.py +53 -0
- spb_onprem/activities/params/activity.py +42 -0
- spb_onprem/activities/params/create_activity.py +80 -0
- spb_onprem/activities/params/delete_activity.py +23 -0
- spb_onprem/activities/params/start_activity.py +59 -0
- spb_onprem/activities/params/update_activity.py +79 -0
- spb_onprem/activities/params/update_activity_history.py +54 -0
- spb_onprem/activities/queries.py +226 -0
- spb_onprem/activities/service.py +315 -0
- spb_onprem/base_model.py +2 -3
- spb_onprem/data/enums/data_type.py +2 -1
- spb_onprem/entities.py +15 -1
- spb_onprem/exports/__init__.py +9 -0
- spb_onprem/exports/entities/__init__.py +7 -0
- spb_onprem/exports/entities/export.py +27 -0
- spb_onprem/exports/params/__init__.py +19 -0
- spb_onprem/exports/params/create_export.py +85 -0
- spb_onprem/exports/params/delete_export.py +30 -0
- spb_onprem/exports/params/export.py +30 -0
- spb_onprem/exports/params/exports.py +74 -0
- spb_onprem/exports/params/update_export.py +98 -0
- spb_onprem/exports/queries.py +158 -0
- spb_onprem/exports/service.py +224 -0
- spb_onprem/searches.py +12 -0
- spb_onprem/slices/params/slices.py +1 -1
- {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/METADATA +1 -1
- {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/RECORD +48 -12
- {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/top_level.txt +1 -0
- tests/__init__.py +1 -0
- tests/activities/__init__.py +1 -0
- tests/activities/real_test.py +66 -0
- tests/activities/test_params.py +67 -0
- tests/activities/test_service.py +139 -0
- tests/exports/__init__.py +1 -0
- tests/exports/real_test.py +130 -0
- tests/exports/test_entities.py +236 -0
- tests/exports/test_integration.py +191 -0
- tests/exports/test_params.py +332 -0
- tests/exports/test_service.py +406 -0
- {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/WHEEL +0 -0
- {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import MagicMock, patch
|
|
3
|
+
|
|
4
|
+
from spb_onprem.exports.service import ExportService
|
|
5
|
+
from spb_onprem.exports.entities import Export
|
|
6
|
+
from spb_onprem.exports.params import ExportFilter
|
|
7
|
+
from spb_onprem.data.params import DataListFilter, DataFilterOptions
|
|
8
|
+
from spb_onprem.data.enums import DataType
|
|
9
|
+
from spb_onprem.base_types import Undefined
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def export_service():
|
|
14
|
+
return ExportService()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TestExportService:
|
|
18
|
+
def test_create_export(self, export_service):
|
|
19
|
+
# Given
|
|
20
|
+
mock_response = {
|
|
21
|
+
"id": "test_export_id",
|
|
22
|
+
"datasetId": "test_dataset_id",
|
|
23
|
+
"name": "test_export_name",
|
|
24
|
+
"dataFilter": {"must": {"keyContains": "test"}},
|
|
25
|
+
"location": "s3://test-bucket/exports/",
|
|
26
|
+
"dataCount": 100,
|
|
27
|
+
"frameCount": 50,
|
|
28
|
+
"annotationCount": 25,
|
|
29
|
+
"meta": {"created_by": "test_user"},
|
|
30
|
+
"createdAt": "2024-01-01T00:00:00Z",
|
|
31
|
+
"completedAt": None
|
|
32
|
+
}
|
|
33
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
34
|
+
|
|
35
|
+
# Create DataListFilter for data filtering
|
|
36
|
+
data_filter = DataListFilter(
|
|
37
|
+
must_filter=DataFilterOptions(key_contains="test")
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# When
|
|
41
|
+
export = export_service.create_export(
|
|
42
|
+
dataset_id="test_dataset_id",
|
|
43
|
+
name="test_export_name",
|
|
44
|
+
data_filter=data_filter,
|
|
45
|
+
meta={"created_by": "test_user"}
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Then
|
|
49
|
+
assert isinstance(export, Export)
|
|
50
|
+
assert export.id == "test_export_id"
|
|
51
|
+
assert export.dataset_id == "test_dataset_id"
|
|
52
|
+
assert export.name == "test_export_name"
|
|
53
|
+
assert isinstance(export.data_filter, DataListFilter)
|
|
54
|
+
assert export.data_filter.must_filter.key_contains == "test"
|
|
55
|
+
assert export.meta == {"created_by": "test_user"}
|
|
56
|
+
|
|
57
|
+
def test_create_export_minimal_params(self, export_service):
|
|
58
|
+
# Given
|
|
59
|
+
mock_response = {
|
|
60
|
+
"id": "test_export_id",
|
|
61
|
+
"datasetId": "test_dataset_id",
|
|
62
|
+
"name": None,
|
|
63
|
+
"dataFilter": None,
|
|
64
|
+
"location": None,
|
|
65
|
+
"dataCount": None,
|
|
66
|
+
"frameCount": None,
|
|
67
|
+
"annotationCount": None,
|
|
68
|
+
"meta": None,
|
|
69
|
+
"createdAt": "2024-01-01T00:00:00Z",
|
|
70
|
+
"completedAt": None
|
|
71
|
+
}
|
|
72
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
73
|
+
|
|
74
|
+
# When
|
|
75
|
+
export = export_service.create_export(dataset_id="test_dataset_id")
|
|
76
|
+
|
|
77
|
+
# Then
|
|
78
|
+
assert isinstance(export, Export)
|
|
79
|
+
assert export.id == "test_export_id"
|
|
80
|
+
assert export.dataset_id == "test_dataset_id"
|
|
81
|
+
assert export.name is None
|
|
82
|
+
assert export.data_filter is None
|
|
83
|
+
assert export.meta is None
|
|
84
|
+
|
|
85
|
+
def test_get_exports(self, export_service):
|
|
86
|
+
# Given
|
|
87
|
+
mock_response = {
|
|
88
|
+
"exports": [
|
|
89
|
+
{
|
|
90
|
+
"id": "test_export_id_1",
|
|
91
|
+
"datasetId": "test_dataset_id",
|
|
92
|
+
"name": "test_export_1",
|
|
93
|
+
"location": "s3://test-bucket/export1/",
|
|
94
|
+
"dataCount": 100,
|
|
95
|
+
"createdAt": "2024-01-01T00:00:00Z"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "test_export_id_2",
|
|
99
|
+
"datasetId": "test_dataset_id",
|
|
100
|
+
"name": "test_export_2",
|
|
101
|
+
"location": "s3://test-bucket/export2/",
|
|
102
|
+
"dataCount": 200,
|
|
103
|
+
"createdAt": "2024-01-02T00:00:00Z"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"next": "next_cursor",
|
|
107
|
+
"totalCount": 2
|
|
108
|
+
}
|
|
109
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
110
|
+
|
|
111
|
+
# When
|
|
112
|
+
exports, next_cursor, total_count = export_service.get_exports(
|
|
113
|
+
dataset_id="test_dataset_id",
|
|
114
|
+
length=10
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Then
|
|
118
|
+
assert len(exports) == 2
|
|
119
|
+
assert all(isinstance(export, Export) for export in exports)
|
|
120
|
+
assert exports[0].id == "test_export_id_1"
|
|
121
|
+
assert exports[1].id == "test_export_id_2"
|
|
122
|
+
assert next_cursor == "next_cursor"
|
|
123
|
+
assert total_count == 2
|
|
124
|
+
|
|
125
|
+
def test_get_exports_with_filter(self, export_service):
|
|
126
|
+
# Given
|
|
127
|
+
mock_response = {
|
|
128
|
+
"exports": [
|
|
129
|
+
{
|
|
130
|
+
"id": "test_export_id_1",
|
|
131
|
+
"datasetId": "test_dataset_id",
|
|
132
|
+
"name": "filtered_export",
|
|
133
|
+
"location": "s3://test-bucket/filtered/",
|
|
134
|
+
"dataCount": 50,
|
|
135
|
+
"createdAt": "2024-01-01T00:00:00Z"
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
"next": None,
|
|
139
|
+
"totalCount": 1
|
|
140
|
+
}
|
|
141
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
142
|
+
|
|
143
|
+
export_filter = ExportFilter(
|
|
144
|
+
must_filter={"name": "filtered_export"}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# When
|
|
148
|
+
exports, next_cursor, total_count = export_service.get_exports(
|
|
149
|
+
dataset_id="test_dataset_id",
|
|
150
|
+
export_filter=export_filter,
|
|
151
|
+
cursor="start_cursor",
|
|
152
|
+
length=5
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Then
|
|
156
|
+
assert len(exports) == 1
|
|
157
|
+
assert exports[0].name == "filtered_export"
|
|
158
|
+
assert next_cursor is None
|
|
159
|
+
assert total_count == 1
|
|
160
|
+
|
|
161
|
+
def test_get_export(self, export_service):
|
|
162
|
+
# Given
|
|
163
|
+
mock_response = {
|
|
164
|
+
"id": "test_export_id",
|
|
165
|
+
"datasetId": "test_dataset_id",
|
|
166
|
+
"name": "single_export",
|
|
167
|
+
"dataFilter": {"must": {"keyContains": "completed"}},
|
|
168
|
+
"location": "s3://test-bucket/single/",
|
|
169
|
+
"dataCount": 75,
|
|
170
|
+
"frameCount": 30,
|
|
171
|
+
"annotationCount": 15,
|
|
172
|
+
"meta": {"processed": True},
|
|
173
|
+
"createdAt": "2024-01-01T00:00:00Z",
|
|
174
|
+
"completedAt": "2024-01-01T01:00:00Z"
|
|
175
|
+
}
|
|
176
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
177
|
+
|
|
178
|
+
# When
|
|
179
|
+
export = export_service.get_export(
|
|
180
|
+
dataset_id="test_dataset_id",
|
|
181
|
+
export_id="test_export_id"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Then
|
|
185
|
+
assert isinstance(export, Export)
|
|
186
|
+
assert export.id == "test_export_id"
|
|
187
|
+
assert export.dataset_id == "test_dataset_id"
|
|
188
|
+
assert export.name == "single_export"
|
|
189
|
+
assert isinstance(export.data_filter, DataListFilter)
|
|
190
|
+
assert export.data_filter.must_filter.key_contains == "completed"
|
|
191
|
+
assert export.location == "s3://test-bucket/single/"
|
|
192
|
+
assert export.data_count == 75
|
|
193
|
+
assert export.frame_count == 30
|
|
194
|
+
assert export.annotation_count == 15
|
|
195
|
+
assert export.meta == {"processed": True}
|
|
196
|
+
assert export.completed_at == "2024-01-01T01:00:00Z"
|
|
197
|
+
|
|
198
|
+
def test_update_export(self, export_service):
|
|
199
|
+
# Given
|
|
200
|
+
mock_response = {
|
|
201
|
+
"id": "test_export_id",
|
|
202
|
+
"datasetId": "test_dataset_id",
|
|
203
|
+
"name": "updated_export_name",
|
|
204
|
+
"dataFilter": {"must": {"keyContains": "updated"}},
|
|
205
|
+
"location": "s3://test-bucket/updated/",
|
|
206
|
+
"dataCount": 150,
|
|
207
|
+
"frameCount": 75,
|
|
208
|
+
"annotationCount": 40,
|
|
209
|
+
"meta": {"updated_by": "test_user", "version": 2},
|
|
210
|
+
"createdAt": "2024-01-01T00:00:00Z",
|
|
211
|
+
"updatedAt": "2024-01-01T12:00:00Z",
|
|
212
|
+
"completedAt": "2024-01-01T13:00:00Z"
|
|
213
|
+
}
|
|
214
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
215
|
+
|
|
216
|
+
# Create DataListFilter for update
|
|
217
|
+
data_filter = DataListFilter(
|
|
218
|
+
must_filter=DataFilterOptions(key_contains="updated")
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# When
|
|
222
|
+
export = export_service.update_export(
|
|
223
|
+
dataset_id="test_dataset_id",
|
|
224
|
+
export_id="test_export_id",
|
|
225
|
+
name="updated_export_name",
|
|
226
|
+
location="s3://test-bucket/updated/",
|
|
227
|
+
data_filter=data_filter,
|
|
228
|
+
data_count=150,
|
|
229
|
+
frame_count=75,
|
|
230
|
+
annotation_count=40,
|
|
231
|
+
meta={"updated_by": "test_user", "version": 2},
|
|
232
|
+
completed_at="2024-01-01T13:00:00Z"
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
# Then
|
|
236
|
+
assert isinstance(export, Export)
|
|
237
|
+
assert export.id == "test_export_id"
|
|
238
|
+
assert export.name == "updated_export_name"
|
|
239
|
+
assert export.location == "s3://test-bucket/updated/"
|
|
240
|
+
assert isinstance(export.data_filter, DataListFilter)
|
|
241
|
+
assert export.data_filter.must_filter.key_contains == "updated"
|
|
242
|
+
assert export.data_count == 150
|
|
243
|
+
assert export.frame_count == 75
|
|
244
|
+
assert export.annotation_count == 40
|
|
245
|
+
assert export.meta == {"updated_by": "test_user", "version": 2}
|
|
246
|
+
assert export.completed_at == "2024-01-01T13:00:00Z"
|
|
247
|
+
|
|
248
|
+
def test_update_export_partial(self, export_service):
|
|
249
|
+
# Given
|
|
250
|
+
mock_response = {
|
|
251
|
+
"id": "test_export_id",
|
|
252
|
+
"datasetId": "test_dataset_id",
|
|
253
|
+
"name": "partially_updated_export",
|
|
254
|
+
"dataFilter": None,
|
|
255
|
+
"location": None,
|
|
256
|
+
"dataCount": None,
|
|
257
|
+
"frameCount": None,
|
|
258
|
+
"annotationCount": None,
|
|
259
|
+
"meta": {"partial_update": True},
|
|
260
|
+
"createdAt": "2024-01-01T00:00:00Z",
|
|
261
|
+
"updatedAt": "2024-01-01T12:00:00Z",
|
|
262
|
+
"completedAt": None
|
|
263
|
+
}
|
|
264
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
265
|
+
|
|
266
|
+
# When
|
|
267
|
+
export = export_service.update_export(
|
|
268
|
+
dataset_id="test_dataset_id",
|
|
269
|
+
export_id="test_export_id",
|
|
270
|
+
name="partially_updated_export",
|
|
271
|
+
meta={"partial_update": True}
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
# Then
|
|
275
|
+
assert isinstance(export, Export)
|
|
276
|
+
assert export.id == "test_export_id"
|
|
277
|
+
assert export.name == "partially_updated_export"
|
|
278
|
+
assert export.meta == {"partial_update": True}
|
|
279
|
+
|
|
280
|
+
def test_delete_export(self, export_service):
|
|
281
|
+
# Given
|
|
282
|
+
mock_response = True
|
|
283
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
284
|
+
|
|
285
|
+
# When
|
|
286
|
+
result = export_service.delete_export(
|
|
287
|
+
dataset_id="test_dataset_id",
|
|
288
|
+
export_id="test_export_id"
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
# Then
|
|
292
|
+
assert result is True
|
|
293
|
+
|
|
294
|
+
def test_delete_export_failed(self, export_service):
|
|
295
|
+
# Given
|
|
296
|
+
mock_response = False
|
|
297
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
298
|
+
|
|
299
|
+
# When
|
|
300
|
+
result = export_service.delete_export(
|
|
301
|
+
dataset_id="test_dataset_id",
|
|
302
|
+
export_id="non_existent_export_id"
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
# Then
|
|
306
|
+
assert result is False
|
|
307
|
+
|
|
308
|
+
def test_delete_export_none_response(self, export_service):
|
|
309
|
+
# Given
|
|
310
|
+
mock_response = None
|
|
311
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
312
|
+
|
|
313
|
+
# When
|
|
314
|
+
result = export_service.delete_export(
|
|
315
|
+
dataset_id="test_dataset_id",
|
|
316
|
+
export_id="test_export_id"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# Then
|
|
320
|
+
assert result is None
|
|
321
|
+
|
|
322
|
+
def test_create_export_with_complex_data_filter(self, export_service):
|
|
323
|
+
# Given
|
|
324
|
+
mock_response = {
|
|
325
|
+
"id": "test_export_id",
|
|
326
|
+
"datasetId": "test_dataset_id",
|
|
327
|
+
"name": "complex_filter_export",
|
|
328
|
+
"dataFilter": {"must": {"keyContains": "validation", "typeIn": ["SUPERB_IMAGE"]}, "not": {"keyContains": "test"}},
|
|
329
|
+
"location": "s3://test-bucket/complex/",
|
|
330
|
+
"dataCount": 200,
|
|
331
|
+
"createdAt": "2024-01-01T00:00:00Z"
|
|
332
|
+
}
|
|
333
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
334
|
+
|
|
335
|
+
# Create complex DataListFilter
|
|
336
|
+
data_filter = DataListFilter(
|
|
337
|
+
must_filter=DataFilterOptions(
|
|
338
|
+
key_contains="validation",
|
|
339
|
+
type_in=[DataType.SUPERB_IMAGE]
|
|
340
|
+
),
|
|
341
|
+
not_filter=DataFilterOptions(
|
|
342
|
+
key_contains="test"
|
|
343
|
+
)
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
# When
|
|
347
|
+
export = export_service.create_export(
|
|
348
|
+
dataset_id="test_dataset_id",
|
|
349
|
+
name="complex_filter_export",
|
|
350
|
+
data_filter=data_filter
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
# Then
|
|
354
|
+
assert isinstance(export, Export)
|
|
355
|
+
assert export.id == "test_export_id"
|
|
356
|
+
assert export.name == "complex_filter_export"
|
|
357
|
+
assert export.data_count == 200
|
|
358
|
+
assert isinstance(export.data_filter, DataListFilter)
|
|
359
|
+
assert export.data_filter.must_filter.key_contains == "validation"
|
|
360
|
+
assert export.data_filter.must_filter.type_in == [DataType.SUPERB_IMAGE]
|
|
361
|
+
assert export.data_filter.not_filter.key_contains == "test"
|
|
362
|
+
|
|
363
|
+
@patch('spb_onprem.exports.service.Queries')
|
|
364
|
+
def test_create_export_query_call(self, mock_queries, export_service):
|
|
365
|
+
# Given
|
|
366
|
+
mock_response = {"id": "test_id", "datasetId": "test_dataset_id"}
|
|
367
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
368
|
+
|
|
369
|
+
mock_variables_func = MagicMock(return_value={"dataset_id": "test_dataset_id"})
|
|
370
|
+
mock_queries.CREATE_EXPORT = {"variables": mock_variables_func}
|
|
371
|
+
|
|
372
|
+
# When
|
|
373
|
+
export_service.create_export(dataset_id="test_dataset_id")
|
|
374
|
+
|
|
375
|
+
# Then
|
|
376
|
+
export_service.request_gql.assert_called_once()
|
|
377
|
+
mock_variables_func.assert_called_once_with(
|
|
378
|
+
dataset_id="test_dataset_id",
|
|
379
|
+
name=Undefined,
|
|
380
|
+
data_filter=Undefined,
|
|
381
|
+
data_count=Undefined,
|
|
382
|
+
frame_count=Undefined,
|
|
383
|
+
annotation_count=Undefined,
|
|
384
|
+
meta=Undefined
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
@patch('spb_onprem.exports.service.Queries')
|
|
388
|
+
def test_get_exports_query_call(self, mock_queries, export_service):
|
|
389
|
+
# Given
|
|
390
|
+
mock_response = {"exports": [], "next": None, "totalCount": 0}
|
|
391
|
+
export_service.request_gql = MagicMock(return_value=mock_response)
|
|
392
|
+
|
|
393
|
+
mock_variables_func = MagicMock(return_value={"dataset_id": "test_dataset_id"})
|
|
394
|
+
mock_queries.GET_EXPORTS = {"variables": mock_variables_func}
|
|
395
|
+
|
|
396
|
+
# When
|
|
397
|
+
export_service.get_exports(dataset_id="test_dataset_id", cursor="test_cursor", length=20)
|
|
398
|
+
|
|
399
|
+
# Then
|
|
400
|
+
export_service.request_gql.assert_called_once()
|
|
401
|
+
mock_variables_func.assert_called_once_with(
|
|
402
|
+
dataset_id="test_dataset_id",
|
|
403
|
+
export_filter=None,
|
|
404
|
+
cursor="test_cursor",
|
|
405
|
+
length=20
|
|
406
|
+
)
|
|
File without changes
|
|
File without changes
|