superb-ai-onprem 0.5.9__py3-none-any.whl → 0.5.11__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 (57) hide show
  1. spb_onprem/__init__.py +8 -0
  2. spb_onprem/_version.py +2 -2
  3. spb_onprem/activities/service.py +1 -2
  4. spb_onprem/contents/params/__init__.py +2 -0
  5. spb_onprem/contents/params/delete_content.py +10 -0
  6. spb_onprem/contents/queries.py +11 -0
  7. spb_onprem/contents/service.py +19 -0
  8. spb_onprem/data/entities/data.py +0 -1
  9. spb_onprem/data/params/__init__.py +8 -0
  10. spb_onprem/data/params/create_data.py +2 -10
  11. spb_onprem/data/params/get_data_detail.py +14 -0
  12. spb_onprem/data/params/get_evaluation_value_list.py +36 -0
  13. spb_onprem/data/params/update_data.py +0 -16
  14. spb_onprem/data/params/upsert_data_meta.py +0 -12
  15. spb_onprem/data/queries.py +72 -6
  16. spb_onprem/data/service.py +103 -108
  17. spb_onprem/datasets/params/__init__.py +2 -0
  18. spb_onprem/datasets/params/delete_dataset.py +12 -0
  19. spb_onprem/datasets/queries.py +11 -0
  20. spb_onprem/datasets/service.py +18 -0
  21. spb_onprem/entities.py +4 -0
  22. spb_onprem/inferences/__init__.py +5 -0
  23. spb_onprem/inferences/service.py +56 -0
  24. spb_onprem/models/__init__.py +7 -0
  25. spb_onprem/models/entities.py +9 -0
  26. spb_onprem/models/params/__init__.py +7 -0
  27. spb_onprem/models/params/delete_model.py +14 -0
  28. spb_onprem/models/params/get_models.py +29 -0
  29. spb_onprem/models/queries.py +33 -0
  30. spb_onprem/models/service.py +76 -0
  31. spb_onprem/predictions/__init__.py +7 -0
  32. spb_onprem/predictions/entities.py +11 -0
  33. spb_onprem/predictions/params/__init__.py +15 -0
  34. spb_onprem/predictions/params/create_prediction_set.py +44 -0
  35. spb_onprem/predictions/params/delete_prediction_from_data.py +20 -0
  36. spb_onprem/predictions/params/delete_prediction_set.py +14 -0
  37. spb_onprem/predictions/params/get_prediction_set.py +14 -0
  38. spb_onprem/predictions/params/get_prediction_sets.py +29 -0
  39. spb_onprem/predictions/params/update_prediction_set_data_info.py +28 -0
  40. spb_onprem/predictions/queries.py +110 -0
  41. spb_onprem/predictions/service.py +225 -0
  42. {superb_ai_onprem-0.5.9.dist-info → superb_ai_onprem-0.5.11.dist-info}/METADATA +1 -1
  43. {superb_ai_onprem-0.5.9.dist-info → superb_ai_onprem-0.5.11.dist-info}/RECORD +57 -25
  44. tests/activities/test_params.py +2 -2
  45. tests/activities/test_service.py +28 -38
  46. tests/data/__init__.py +0 -0
  47. tests/data/test_data_service.py +412 -0
  48. tests/datasets/__init__.py +1 -0
  49. tests/datasets/test_dataset_service.py +135 -0
  50. tests/exports/test_service.py +1 -0
  51. tests/models/__init__.py +1 -0
  52. tests/models/test_model_service.py +249 -0
  53. tests/predictions/__init__.py +1 -0
  54. tests/predictions/test_prediction_service.py +359 -0
  55. {superb_ai_onprem-0.5.9.dist-info → superb_ai_onprem-0.5.11.dist-info}/WHEEL +0 -0
  56. {superb_ai_onprem-0.5.9.dist-info → superb_ai_onprem-0.5.11.dist-info}/licenses/LICENSE +0 -0
  57. {superb_ai_onprem-0.5.9.dist-info → superb_ai_onprem-0.5.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,412 @@
1
+ import pytest
2
+ from unittest.mock import Mock, patch
3
+
4
+ from spb_onprem.data.service import DataService
5
+ from spb_onprem.data.queries import Queries
6
+ from spb_onprem.data.entities import Data
7
+ from spb_onprem.exceptions import BadParameterError
8
+
9
+
10
+ class TestDataService:
11
+ """Test cases for DataService with new get_data_detail method."""
12
+
13
+ def setup_method(self):
14
+ """Set up test fixtures before each test method."""
15
+ self.data_service = DataService()
16
+ self.data_service.request_gql = Mock()
17
+
18
+ def test_get_data_detail_success(self):
19
+ """Test successful data detail retrieval."""
20
+ # Arrange
21
+ dataset_id = "dataset-123"
22
+ data_id = "data-456"
23
+ mock_response = {
24
+ "data": {
25
+ "id": data_id,
26
+ "datasetId": dataset_id,
27
+ "scene": [
28
+ {
29
+ "id": "scene-1",
30
+ "content": {"id": "content-1"}
31
+ }
32
+ ],
33
+ "annotation": {
34
+ "versions": [
35
+ {
36
+ "id": "annotation-1",
37
+ "content": {"id": "content-2"}
38
+ }
39
+ ]
40
+ },
41
+ "predictions": [
42
+ {
43
+ "id": "prediction-1",
44
+ "content": {"id": "content-3"}
45
+ }
46
+ ],
47
+ "thumbnail": {
48
+ "id": "thumbnail-1"
49
+ }
50
+ }
51
+ }
52
+ self.data_service.request_gql.return_value = mock_response
53
+
54
+ # Act
55
+ result = self.data_service.get_data_detail(dataset_id, data_id)
56
+
57
+ # Assert
58
+ assert isinstance(result, Data)
59
+ assert result.id == data_id
60
+ assert result.dataset_id == dataset_id
61
+ self.data_service.request_gql.assert_called_once_with(
62
+ Queries.GET_DETAIL,
63
+ Queries.GET_DETAIL["variables"](dataset_id, data_id)
64
+ )
65
+
66
+ def test_get_data_detail_missing_dataset_id(self):
67
+ """Test get_data_detail with missing dataset_id."""
68
+ # Arrange
69
+ dataset_id = None
70
+ data_id = "data-456"
71
+
72
+ # Act & Assert
73
+ with pytest.raises(BadParameterError, match="dataset_id is required"):
74
+ self.data_service.get_data_detail(dataset_id, data_id)
75
+
76
+ def test_get_data_detail_missing_data_id(self):
77
+ """Test get_data_detail with missing data_id."""
78
+ # Arrange
79
+ dataset_id = "dataset-123"
80
+ data_id = None
81
+
82
+ # Act & Assert
83
+ with pytest.raises(BadParameterError, match="data_id is required"):
84
+ self.data_service.get_data_detail(dataset_id, data_id)
85
+
86
+ def test_get_data_detail_empty_response(self):
87
+ """Test get_data_detail with empty data response."""
88
+ # Arrange
89
+ dataset_id = "dataset-123"
90
+ data_id = "data-456"
91
+ mock_response = {"data": {}}
92
+ self.data_service.request_gql.return_value = mock_response
93
+
94
+ # Act
95
+ result = self.data_service.get_data_detail(dataset_id, data_id)
96
+
97
+ # Assert
98
+ assert isinstance(result, Data)
99
+ self.data_service.request_gql.assert_called_once_with(
100
+ Queries.GET_DETAIL,
101
+ Queries.GET_DETAIL["variables"](dataset_id, data_id)
102
+ )
103
+
104
+ def test_get_data_detail_missing_data_field(self):
105
+ """Test get_data_detail with missing data field in response."""
106
+ # Arrange
107
+ dataset_id = "dataset-123"
108
+ data_id = "data-456"
109
+ mock_response = {} # No data field
110
+ self.data_service.request_gql.return_value = mock_response
111
+
112
+ # Act
113
+ result = self.data_service.get_data_detail(dataset_id, data_id)
114
+
115
+ # Assert
116
+ assert isinstance(result, Data)
117
+ self.data_service.request_gql.assert_called_once_with(
118
+ Queries.GET_DETAIL,
119
+ Queries.GET_DETAIL["variables"](dataset_id, data_id)
120
+ )
121
+
122
+ def test_get_data_detail_query_structure(self):
123
+ """Test that GET_DETAIL query has correct structure."""
124
+ # Arrange & Act
125
+ query_structure = Queries.GET_DETAIL
126
+
127
+ # Assert
128
+ assert query_structure["name"] == "getDataDetail"
129
+ assert "query GetDataDetail($datasetId: String!, $id: String!)" in query_structure["query"]
130
+ assert "data(datasetId: $datasetId, id: $id)" in query_structure["query"]
131
+ assert callable(query_structure["variables"])
132
+
133
+ def test_get_data_detail_variables_function(self):
134
+ """Test that variables function generates correct parameters."""
135
+ # Arrange
136
+ dataset_id = "dataset-789"
137
+ data_id = "data-101"
138
+
139
+ # Act
140
+ variables = Queries.GET_DETAIL["variables"](dataset_id, data_id)
141
+
142
+ # Assert
143
+ assert variables == {
144
+ "datasetId": dataset_id,
145
+ "id": data_id
146
+ }
147
+
148
+ def test_get_data_detail_with_nested_relationships(self):
149
+ """Test get_data_detail with complex nested relationships."""
150
+ # Arrange
151
+ dataset_id = "dataset-complex"
152
+ data_id = "data-complex"
153
+ mock_response = {
154
+ "data": {
155
+ "id": data_id,
156
+ "datasetId": dataset_id,
157
+ "scene": [
158
+ {
159
+ "id": "scene-1",
160
+ "content": {"id": "scene-content-1"}
161
+ },
162
+ {
163
+ "id": "scene-2",
164
+ "content": {"id": "scene-content-2"}
165
+ }
166
+ ],
167
+ "annotation": {
168
+ "versions": [
169
+ {
170
+ "id": "annotation-v1",
171
+ "content": {"id": "annotation-content-1"}
172
+ },
173
+ {
174
+ "id": "annotation-v2",
175
+ "content": {"id": "annotation-content-2"}
176
+ }
177
+ ]
178
+ },
179
+ "predictions": [
180
+ {
181
+ "id": "prediction-1",
182
+ "content": {"id": "prediction-content-1"}
183
+ }
184
+ ],
185
+ "thumbnail": {
186
+ "id": "thumbnail-complex"
187
+ }
188
+ }
189
+ }
190
+ self.data_service.request_gql.return_value = mock_response
191
+
192
+ # Act
193
+ result = self.data_service.get_data_detail(dataset_id, data_id)
194
+
195
+ # Assert
196
+ assert isinstance(result, Data)
197
+ assert result.id == data_id
198
+ assert len(result.scene) == 2
199
+ assert len(result.annotation.versions) == 2
200
+ assert len(result.predictions) == 1
201
+ assert result.thumbnail.id == "thumbnail-complex"
202
+
203
+ def test_get_data_detail_exception_handling(self):
204
+ """Test get_data_detail exception handling."""
205
+ # Arrange
206
+ dataset_id = "dataset-error"
207
+ data_id = "data-error"
208
+ self.data_service.request_gql.side_effect = Exception("GraphQL error")
209
+
210
+ # Act & Assert
211
+ with pytest.raises(Exception, match="GraphQL error"):
212
+ self.data_service.get_data_detail(dataset_id, data_id)
213
+
214
+ self.data_service.request_gql.assert_called_once()
215
+
216
+ def test_get_evaluation_value_list_success(self):
217
+ """Test successful evaluation value list retrieval."""
218
+ # Arrange
219
+ dataset_id = "dataset-123"
220
+ prediction_set_id = "pred-set-456"
221
+ filter_dict = {"score": {"min": 0.8}}
222
+ length = 25
223
+ cursor = "cursor-abc"
224
+
225
+ mock_response = {
226
+ "evaluationValueList": {
227
+ "totalCount": 100,
228
+ "next": "cursor-def",
229
+ "data": [
230
+ {"dataId": "data-1"},
231
+ {"dataId": "data-2"},
232
+ {"dataId": "data-3"}
233
+ ]
234
+ }
235
+ }
236
+ self.data_service.request_gql.return_value = mock_response
237
+
238
+ # Act
239
+ result = self.data_service.get_evaluation_value_list(
240
+ dataset_id=dataset_id,
241
+ prediction_set_id=prediction_set_id,
242
+ filter=filter_dict,
243
+ length=length,
244
+ cursor=cursor
245
+ )
246
+
247
+ # Assert
248
+ expected_result = {
249
+ "totalCount": 100,
250
+ "next": "cursor-def",
251
+ "data": [
252
+ {"dataId": "data-1"},
253
+ {"dataId": "data-2"},
254
+ {"dataId": "data-3"}
255
+ ]
256
+ }
257
+ assert result == expected_result
258
+ self.data_service.request_gql.assert_called_once_with(
259
+ Queries.GET_EVALUATION_VALUE_LIST,
260
+ Queries.GET_EVALUATION_VALUE_LIST["variables"](
261
+ dataset_id=dataset_id,
262
+ prediction_set_id=prediction_set_id,
263
+ filter=filter_dict,
264
+ length=length,
265
+ cursor=cursor
266
+ )
267
+ )
268
+
269
+ def test_get_evaluation_value_list_without_filter(self):
270
+ """Test evaluation value list retrieval without filter."""
271
+ # Arrange
272
+ dataset_id = "dataset-123"
273
+ prediction_set_id = "pred-set-456"
274
+
275
+ mock_response = {
276
+ "evaluationValueList": {
277
+ "totalCount": 50,
278
+ "next": None,
279
+ "data": [{"dataId": "data-1"}]
280
+ }
281
+ }
282
+ self.data_service.request_gql.return_value = mock_response
283
+
284
+ # Act
285
+ result = self.data_service.get_evaluation_value_list(
286
+ dataset_id=dataset_id,
287
+ prediction_set_id=prediction_set_id
288
+ )
289
+
290
+ # Assert
291
+ assert result["totalCount"] == 50
292
+ assert result["next"] is None
293
+ assert len(result["data"]) == 1
294
+
295
+ def test_get_evaluation_value_list_missing_dataset_id(self):
296
+ """Test evaluation value list with missing dataset_id."""
297
+ # Arrange
298
+ prediction_set_id = "pred-set-456"
299
+
300
+ # Act & Assert
301
+ with pytest.raises(BadParameterError, match="dataset_id is required"):
302
+ self.data_service.get_evaluation_value_list(
303
+ dataset_id=None,
304
+ prediction_set_id=prediction_set_id
305
+ )
306
+
307
+ def test_get_evaluation_value_list_missing_prediction_set_id(self):
308
+ """Test evaluation value list with missing prediction_set_id."""
309
+ # Arrange
310
+ dataset_id = "dataset-123"
311
+
312
+ # Act & Assert
313
+ with pytest.raises(BadParameterError, match="prediction_set_id is required"):
314
+ self.data_service.get_evaluation_value_list(
315
+ dataset_id=dataset_id,
316
+ prediction_set_id=None
317
+ )
318
+
319
+ def test_get_evaluation_value_list_empty_response(self):
320
+ """Test evaluation value list with empty response."""
321
+ # Arrange
322
+ dataset_id = "dataset-123"
323
+ prediction_set_id = "pred-set-456"
324
+
325
+ mock_response = {}
326
+ self.data_service.request_gql.return_value = mock_response
327
+
328
+ # Act
329
+ result = self.data_service.get_evaluation_value_list(
330
+ dataset_id=dataset_id,
331
+ prediction_set_id=prediction_set_id
332
+ )
333
+
334
+ # Assert
335
+ assert result == {}
336
+
337
+ def test_get_total_data_id_count_in_evaluation_value_success(self):
338
+ """Test successful total count retrieval."""
339
+ # Arrange
340
+ dataset_id = "dataset-123"
341
+ prediction_set_id = "pred-set-456"
342
+ filter_dict = {"score": {"min": 0.8}}
343
+
344
+ mock_response = {
345
+ "evaluationValueList": {
346
+ "totalCount": 150,
347
+ "next": "cursor-abc",
348
+ "data": [{"dataId": "data-1"}]
349
+ }
350
+ }
351
+ self.data_service.request_gql.return_value = mock_response
352
+
353
+ # Act
354
+ result = self.data_service.get_total_data_id_count_in_evaluation_value(
355
+ dataset_id=dataset_id,
356
+ prediction_set_id=prediction_set_id,
357
+ filter=filter_dict
358
+ )
359
+
360
+ # Assert
361
+ assert result == 150
362
+ self.data_service.request_gql.assert_called_once_with(
363
+ Queries.GET_EVALUATION_VALUE_LIST,
364
+ Queries.GET_EVALUATION_VALUE_LIST["variables"](
365
+ dataset_id=dataset_id,
366
+ prediction_set_id=prediction_set_id,
367
+ filter=filter_dict,
368
+ length=1
369
+ )
370
+ )
371
+
372
+ def test_get_total_data_id_count_in_evaluation_value_zero_count(self):
373
+ """Test total count retrieval with zero results."""
374
+ # Arrange
375
+ dataset_id = "dataset-123"
376
+ prediction_set_id = "pred-set-456"
377
+
378
+ mock_response = {
379
+ "evaluationValueList": {
380
+ "totalCount": 0,
381
+ "next": None,
382
+ "data": []
383
+ }
384
+ }
385
+ self.data_service.request_gql.return_value = mock_response
386
+
387
+ # Act
388
+ result = self.data_service.get_total_data_id_count_in_evaluation_value(
389
+ dataset_id=dataset_id,
390
+ prediction_set_id=prediction_set_id
391
+ )
392
+
393
+ # Assert
394
+ assert result == 0
395
+
396
+ def test_get_total_data_id_count_in_evaluation_value_missing_response(self):
397
+ """Test total count retrieval with missing response fields."""
398
+ # Arrange
399
+ dataset_id = "dataset-123"
400
+ prediction_set_id = "pred-set-456"
401
+
402
+ mock_response = {}
403
+ self.data_service.request_gql.return_value = mock_response
404
+
405
+ # Act
406
+ result = self.data_service.get_total_data_id_count_in_evaluation_value(
407
+ dataset_id=dataset_id,
408
+ prediction_set_id=prediction_set_id
409
+ )
410
+
411
+ # Assert
412
+ assert result == 0
@@ -0,0 +1 @@
1
+ # Datasets test package
@@ -0,0 +1,135 @@
1
+ import pytest
2
+ from unittest.mock import Mock
3
+
4
+ from spb_onprem.datasets.service import DatasetService
5
+ from spb_onprem.datasets.queries import Queries
6
+ from spb_onprem.exceptions import BadParameterError
7
+
8
+
9
+ class TestDatasetService:
10
+ """Test cases for DatasetService delete_dataset method."""
11
+
12
+ def setup_method(self):
13
+ """Set up test fixtures before each test method."""
14
+ self.dataset_service = DatasetService()
15
+ self.dataset_service.request_gql = Mock()
16
+
17
+ def test_delete_dataset_success(self):
18
+ """Test successful dataset deletion."""
19
+ # Arrange
20
+ dataset_id = "dataset-123"
21
+ mock_response = {"deleteDataset": True}
22
+ self.dataset_service.request_gql.return_value = mock_response
23
+
24
+ # Act
25
+ result = self.dataset_service.delete_dataset(dataset_id)
26
+
27
+ # Assert
28
+ assert result is True
29
+ self.dataset_service.request_gql.assert_called_once_with(
30
+ Queries.DELETE_DATASET,
31
+ Queries.DELETE_DATASET["variables"](dataset_id=dataset_id)
32
+ )
33
+
34
+ def test_delete_dataset_failure(self):
35
+ """Test dataset deletion failure."""
36
+ # Arrange
37
+ dataset_id = "nonexistent-dataset"
38
+ mock_response = {"deleteDataset": False}
39
+ self.dataset_service.request_gql.return_value = mock_response
40
+
41
+ # Act
42
+ result = self.dataset_service.delete_dataset(dataset_id)
43
+
44
+ # Assert
45
+ assert result is False
46
+ self.dataset_service.request_gql.assert_called_once_with(
47
+ Queries.DELETE_DATASET,
48
+ Queries.DELETE_DATASET["variables"](dataset_id=dataset_id)
49
+ )
50
+
51
+ def test_delete_dataset_missing_response(self):
52
+ """Test dataset deletion with missing response field."""
53
+ # Arrange
54
+ dataset_id = "dataset-123"
55
+ mock_response = {}
56
+ self.dataset_service.request_gql.return_value = mock_response
57
+
58
+ # Act
59
+ result = self.dataset_service.delete_dataset(dataset_id)
60
+
61
+ # Assert
62
+ assert result is False
63
+
64
+ def test_delete_dataset_missing_dataset_id(self):
65
+ """Test delete dataset with missing dataset_id."""
66
+ # Act & Assert
67
+ with pytest.raises(BadParameterError, match="dataset_id is required"):
68
+ self.dataset_service.delete_dataset(dataset_id=None)
69
+
70
+ def test_delete_dataset_empty_string_id(self):
71
+ """Test delete dataset with empty string ID."""
72
+ # Arrange
73
+ dataset_id = ""
74
+
75
+ # Act & Assert
76
+ # Empty string should be allowed by the service, but would fail at GraphQL level
77
+ mock_response = {"deleteDataset": False}
78
+ self.dataset_service.request_gql.return_value = mock_response
79
+
80
+ result = self.dataset_service.delete_dataset(dataset_id)
81
+ assert result is False
82
+
83
+ def test_delete_dataset_query_structure(self):
84
+ """Test that delete dataset uses correct query structure."""
85
+ # Arrange
86
+ dataset_id = "test-dataset"
87
+ mock_response = {"deleteDataset": True}
88
+ self.dataset_service.request_gql.return_value = mock_response
89
+
90
+ # Act
91
+ self.dataset_service.delete_dataset(dataset_id)
92
+
93
+ # Assert - Verify the query structure
94
+ call_args = self.dataset_service.request_gql.call_args
95
+ query = call_args[0][0] # First positional argument
96
+ variables = call_args[0][1] # Second positional argument
97
+
98
+ # Check query contains expected mutation
99
+ assert query["name"] == "deleteDataset"
100
+ assert "mutation DeleteDataset" in query["query"]
101
+ assert "deleteDataset(datasetId: $dataset_id)" in query["query"]
102
+
103
+ # Check variables function is called correctly
104
+ expected_variables = {"dataset_id": dataset_id}
105
+ assert variables == expected_variables
106
+
107
+ def test_delete_dataset_variables_function(self):
108
+ """Test that variables function works correctly."""
109
+ # Arrange
110
+ dataset_id = "test-variables-dataset"
111
+
112
+ # Act - Call the variables function directly
113
+ variables = Queries.DELETE_DATASET["variables"](dataset_id)
114
+
115
+ # Assert
116
+ expected_variables = {"dataset_id": dataset_id}
117
+ assert variables == expected_variables
118
+
119
+ def test_delete_dataset_with_special_characters(self):
120
+ """Test dataset deletion with special characters in ID."""
121
+ # Arrange
122
+ dataset_id = "dataset-with-special-chars_123@test"
123
+ mock_response = {"deleteDataset": True}
124
+ self.dataset_service.request_gql.return_value = mock_response
125
+
126
+ # Act
127
+ result = self.dataset_service.delete_dataset(dataset_id)
128
+
129
+ # Assert
130
+ assert result is True
131
+
132
+ # Verify the special characters are passed through correctly
133
+ call_args = self.dataset_service.request_gql.call_args
134
+ variables = call_args[0][1]
135
+ assert variables["dataset_id"] == dataset_id
@@ -378,6 +378,7 @@ class TestExportService:
378
378
  dataset_id="test_dataset_id",
379
379
  name=Undefined,
380
380
  data_filter=Undefined,
381
+ location=Undefined,
381
382
  data_count=Undefined,
382
383
  frame_count=Undefined,
383
384
  annotation_count=Undefined,
@@ -0,0 +1 @@
1
+ # Models test package