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.

Files changed (48) hide show
  1. spb_onprem/__init__.py +26 -3
  2. spb_onprem/_version.py +2 -2
  3. spb_onprem/activities/__init__.py +0 -0
  4. spb_onprem/activities/entities/__init__.py +10 -0
  5. spb_onprem/activities/entities/activity.py +39 -0
  6. spb_onprem/activities/entities/activity_history.py +31 -0
  7. spb_onprem/activities/params/__init__.py +23 -0
  8. spb_onprem/activities/params/activities.py +53 -0
  9. spb_onprem/activities/params/activity.py +42 -0
  10. spb_onprem/activities/params/create_activity.py +80 -0
  11. spb_onprem/activities/params/delete_activity.py +23 -0
  12. spb_onprem/activities/params/start_activity.py +59 -0
  13. spb_onprem/activities/params/update_activity.py +79 -0
  14. spb_onprem/activities/params/update_activity_history.py +54 -0
  15. spb_onprem/activities/queries.py +226 -0
  16. spb_onprem/activities/service.py +315 -0
  17. spb_onprem/base_model.py +2 -3
  18. spb_onprem/data/enums/data_type.py +2 -1
  19. spb_onprem/entities.py +15 -1
  20. spb_onprem/exports/__init__.py +9 -0
  21. spb_onprem/exports/entities/__init__.py +7 -0
  22. spb_onprem/exports/entities/export.py +27 -0
  23. spb_onprem/exports/params/__init__.py +19 -0
  24. spb_onprem/exports/params/create_export.py +85 -0
  25. spb_onprem/exports/params/delete_export.py +30 -0
  26. spb_onprem/exports/params/export.py +30 -0
  27. spb_onprem/exports/params/exports.py +74 -0
  28. spb_onprem/exports/params/update_export.py +98 -0
  29. spb_onprem/exports/queries.py +158 -0
  30. spb_onprem/exports/service.py +224 -0
  31. spb_onprem/searches.py +12 -0
  32. spb_onprem/slices/params/slices.py +1 -1
  33. {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/METADATA +1 -1
  34. {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/RECORD +48 -12
  35. {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/top_level.txt +1 -0
  36. tests/__init__.py +1 -0
  37. tests/activities/__init__.py +1 -0
  38. tests/activities/real_test.py +66 -0
  39. tests/activities/test_params.py +67 -0
  40. tests/activities/test_service.py +139 -0
  41. tests/exports/__init__.py +1 -0
  42. tests/exports/real_test.py +130 -0
  43. tests/exports/test_entities.py +236 -0
  44. tests/exports/test_integration.py +191 -0
  45. tests/exports/test_params.py +332 -0
  46. tests/exports/test_service.py +406 -0
  47. {superb_ai_onprem-0.1.6.dist-info → superb_ai_onprem-0.3.0.dist-info}/WHEEL +0 -0
  48. {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
+ )