opik 1.9.41__py3-none-any.whl → 1.9.86__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.
Files changed (192) hide show
  1. opik/api_objects/attachment/attachment_context.py +36 -0
  2. opik/api_objects/attachment/attachments_extractor.py +153 -0
  3. opik/api_objects/attachment/client.py +1 -0
  4. opik/api_objects/attachment/converters.py +2 -0
  5. opik/api_objects/attachment/decoder.py +18 -0
  6. opik/api_objects/attachment/decoder_base64.py +83 -0
  7. opik/api_objects/attachment/decoder_helpers.py +137 -0
  8. opik/api_objects/constants.py +2 -0
  9. opik/api_objects/dataset/dataset.py +133 -40
  10. opik/api_objects/dataset/rest_operations.py +2 -0
  11. opik/api_objects/experiment/experiment.py +6 -0
  12. opik/api_objects/helpers.py +8 -4
  13. opik/api_objects/local_recording.py +6 -5
  14. opik/api_objects/observation_data.py +101 -0
  15. opik/api_objects/opik_client.py +78 -45
  16. opik/api_objects/opik_query_language.py +9 -3
  17. opik/api_objects/prompt/chat/chat_prompt.py +18 -1
  18. opik/api_objects/prompt/client.py +8 -1
  19. opik/api_objects/span/span_data.py +3 -88
  20. opik/api_objects/threads/threads_client.py +7 -4
  21. opik/api_objects/trace/trace_data.py +3 -74
  22. opik/api_objects/validation_helpers.py +3 -3
  23. opik/cli/exports/__init__.py +131 -0
  24. opik/cli/exports/dataset.py +278 -0
  25. opik/cli/exports/experiment.py +784 -0
  26. opik/cli/exports/project.py +685 -0
  27. opik/cli/exports/prompt.py +578 -0
  28. opik/cli/exports/utils.py +406 -0
  29. opik/cli/harbor.py +39 -0
  30. opik/cli/imports/__init__.py +439 -0
  31. opik/cli/imports/dataset.py +143 -0
  32. opik/cli/imports/experiment.py +1192 -0
  33. opik/cli/imports/project.py +262 -0
  34. opik/cli/imports/prompt.py +177 -0
  35. opik/cli/imports/utils.py +280 -0
  36. opik/cli/main.py +14 -12
  37. opik/config.py +12 -1
  38. opik/datetime_helpers.py +12 -0
  39. opik/decorator/arguments_helpers.py +4 -1
  40. opik/decorator/base_track_decorator.py +111 -37
  41. opik/decorator/context_manager/span_context_manager.py +5 -1
  42. opik/decorator/generator_wrappers.py +5 -4
  43. opik/decorator/span_creation_handler.py +13 -4
  44. opik/evaluation/engine/engine.py +111 -28
  45. opik/evaluation/engine/evaluation_tasks_executor.py +71 -19
  46. opik/evaluation/evaluator.py +12 -0
  47. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/metric.py +3 -1
  48. opik/evaluation/metrics/conversation/llm_judges/session_completeness/metric.py +3 -1
  49. opik/evaluation/metrics/conversation/llm_judges/user_frustration/metric.py +3 -1
  50. opik/evaluation/metrics/heuristics/equals.py +11 -7
  51. opik/evaluation/metrics/llm_judges/answer_relevance/metric.py +3 -1
  52. opik/evaluation/metrics/llm_judges/context_precision/metric.py +3 -1
  53. opik/evaluation/metrics/llm_judges/context_recall/metric.py +3 -1
  54. opik/evaluation/metrics/llm_judges/factuality/metric.py +1 -1
  55. opik/evaluation/metrics/llm_judges/g_eval/metric.py +3 -1
  56. opik/evaluation/metrics/llm_judges/hallucination/metric.py +3 -1
  57. opik/evaluation/metrics/llm_judges/moderation/metric.py +3 -1
  58. opik/evaluation/metrics/llm_judges/structure_output_compliance/metric.py +3 -1
  59. opik/evaluation/metrics/llm_judges/syc_eval/metric.py +4 -2
  60. opik/evaluation/metrics/llm_judges/trajectory_accuracy/metric.py +3 -1
  61. opik/evaluation/metrics/llm_judges/usefulness/metric.py +3 -1
  62. opik/evaluation/metrics/ragas_metric.py +43 -23
  63. opik/evaluation/models/litellm/litellm_chat_model.py +7 -2
  64. opik/evaluation/models/litellm/util.py +4 -20
  65. opik/evaluation/models/models_factory.py +19 -5
  66. opik/evaluation/rest_operations.py +3 -3
  67. opik/evaluation/threads/helpers.py +3 -2
  68. opik/file_upload/file_uploader.py +13 -0
  69. opik/file_upload/upload_options.py +2 -0
  70. opik/integrations/adk/legacy_opik_tracer.py +9 -11
  71. opik/integrations/adk/opik_tracer.py +2 -2
  72. opik/integrations/adk/patchers/adk_otel_tracer/opik_adk_otel_tracer.py +2 -2
  73. opik/integrations/dspy/callback.py +100 -14
  74. opik/integrations/dspy/parsers.py +168 -0
  75. opik/integrations/harbor/__init__.py +17 -0
  76. opik/integrations/harbor/experiment_service.py +269 -0
  77. opik/integrations/harbor/opik_tracker.py +528 -0
  78. opik/integrations/haystack/opik_tracer.py +2 -2
  79. opik/integrations/langchain/__init__.py +15 -2
  80. opik/integrations/langchain/langgraph_tracer_injector.py +88 -0
  81. opik/integrations/langchain/opik_tracer.py +258 -160
  82. opik/integrations/langchain/provider_usage_extractors/langchain_run_helpers/helpers.py +7 -4
  83. opik/integrations/llama_index/callback.py +43 -6
  84. opik/integrations/openai/agents/opik_tracing_processor.py +8 -10
  85. opik/integrations/openai/opik_tracker.py +99 -4
  86. opik/integrations/openai/videos/__init__.py +9 -0
  87. opik/integrations/openai/videos/binary_response_write_to_file_decorator.py +88 -0
  88. opik/integrations/openai/videos/videos_create_decorator.py +159 -0
  89. opik/integrations/openai/videos/videos_download_decorator.py +110 -0
  90. opik/message_processing/batching/base_batcher.py +14 -21
  91. opik/message_processing/batching/batch_manager.py +22 -10
  92. opik/message_processing/batching/batchers.py +32 -40
  93. opik/message_processing/batching/flushing_thread.py +0 -3
  94. opik/message_processing/emulation/emulator_message_processor.py +36 -1
  95. opik/message_processing/emulation/models.py +21 -0
  96. opik/message_processing/messages.py +9 -0
  97. opik/message_processing/preprocessing/__init__.py +0 -0
  98. opik/message_processing/preprocessing/attachments_preprocessor.py +70 -0
  99. opik/message_processing/preprocessing/batching_preprocessor.py +53 -0
  100. opik/message_processing/preprocessing/constants.py +1 -0
  101. opik/message_processing/preprocessing/file_upload_preprocessor.py +38 -0
  102. opik/message_processing/preprocessing/preprocessor.py +36 -0
  103. opik/message_processing/processors/__init__.py +0 -0
  104. opik/message_processing/processors/attachments_extraction_processor.py +146 -0
  105. opik/message_processing/{message_processors.py → processors/message_processors.py} +15 -1
  106. opik/message_processing/{message_processors_chain.py → processors/message_processors_chain.py} +3 -2
  107. opik/message_processing/{online_message_processor.py → processors/online_message_processor.py} +11 -9
  108. opik/message_processing/queue_consumer.py +4 -2
  109. opik/message_processing/streamer.py +71 -33
  110. opik/message_processing/streamer_constructors.py +36 -8
  111. opik/plugins/pytest/experiment_runner.py +1 -1
  112. opik/plugins/pytest/hooks.py +5 -3
  113. opik/rest_api/__init__.py +38 -0
  114. opik/rest_api/datasets/client.py +249 -148
  115. opik/rest_api/datasets/raw_client.py +356 -217
  116. opik/rest_api/experiments/client.py +26 -0
  117. opik/rest_api/experiments/raw_client.py +26 -0
  118. opik/rest_api/llm_provider_key/client.py +4 -4
  119. opik/rest_api/llm_provider_key/raw_client.py +4 -4
  120. opik/rest_api/llm_provider_key/types/provider_api_key_write_provider.py +2 -1
  121. opik/rest_api/manual_evaluation/client.py +101 -0
  122. opik/rest_api/manual_evaluation/raw_client.py +172 -0
  123. opik/rest_api/optimizations/client.py +0 -166
  124. opik/rest_api/optimizations/raw_client.py +0 -248
  125. opik/rest_api/projects/client.py +9 -0
  126. opik/rest_api/projects/raw_client.py +13 -0
  127. opik/rest_api/projects/types/project_metric_request_public_metric_type.py +4 -0
  128. opik/rest_api/prompts/client.py +130 -2
  129. opik/rest_api/prompts/raw_client.py +175 -0
  130. opik/rest_api/traces/client.py +101 -0
  131. opik/rest_api/traces/raw_client.py +120 -0
  132. opik/rest_api/types/__init__.py +46 -0
  133. opik/rest_api/types/audio_url.py +19 -0
  134. opik/rest_api/types/audio_url_public.py +19 -0
  135. opik/rest_api/types/audio_url_write.py +19 -0
  136. opik/rest_api/types/automation_rule_evaluator.py +38 -2
  137. opik/rest_api/types/automation_rule_evaluator_object_object_public.py +33 -2
  138. opik/rest_api/types/automation_rule_evaluator_public.py +33 -2
  139. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python.py +22 -0
  140. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_public.py +22 -0
  141. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_write.py +22 -0
  142. opik/rest_api/types/automation_rule_evaluator_update.py +27 -1
  143. opik/rest_api/types/automation_rule_evaluator_update_span_user_defined_metric_python.py +22 -0
  144. opik/rest_api/types/automation_rule_evaluator_write.py +27 -1
  145. opik/rest_api/types/dataset_item.py +1 -1
  146. opik/rest_api/types/dataset_item_batch.py +4 -0
  147. opik/rest_api/types/dataset_item_changes_public.py +5 -0
  148. opik/rest_api/types/dataset_item_compare.py +1 -1
  149. opik/rest_api/types/dataset_item_filter.py +4 -0
  150. opik/rest_api/types/dataset_item_page_compare.py +0 -1
  151. opik/rest_api/types/dataset_item_page_public.py +0 -1
  152. opik/rest_api/types/dataset_item_public.py +1 -1
  153. opik/rest_api/types/dataset_version_public.py +5 -0
  154. opik/rest_api/types/dataset_version_summary.py +5 -0
  155. opik/rest_api/types/dataset_version_summary_public.py +5 -0
  156. opik/rest_api/types/experiment.py +9 -0
  157. opik/rest_api/types/experiment_public.py +9 -0
  158. opik/rest_api/types/llm_as_judge_message_content.py +2 -0
  159. opik/rest_api/types/llm_as_judge_message_content_public.py +2 -0
  160. opik/rest_api/types/llm_as_judge_message_content_write.py +2 -0
  161. opik/rest_api/types/manual_evaluation_request_entity_type.py +1 -1
  162. opik/rest_api/types/project.py +1 -0
  163. opik/rest_api/types/project_detailed.py +1 -0
  164. opik/rest_api/types/project_metric_response_public_metric_type.py +4 -0
  165. opik/rest_api/types/project_reference.py +31 -0
  166. opik/rest_api/types/project_reference_public.py +31 -0
  167. opik/rest_api/types/project_stats_summary_item.py +1 -0
  168. opik/rest_api/types/prompt_version.py +1 -0
  169. opik/rest_api/types/prompt_version_detail.py +1 -0
  170. opik/rest_api/types/prompt_version_page_public.py +5 -0
  171. opik/rest_api/types/prompt_version_public.py +1 -0
  172. opik/rest_api/types/prompt_version_update.py +33 -0
  173. opik/rest_api/types/provider_api_key.py +5 -1
  174. opik/rest_api/types/provider_api_key_provider.py +2 -1
  175. opik/rest_api/types/provider_api_key_public.py +5 -1
  176. opik/rest_api/types/provider_api_key_public_provider.py +2 -1
  177. opik/rest_api/types/service_toggles_config.py +11 -1
  178. opik/rest_api/types/span_user_defined_metric_python_code.py +20 -0
  179. opik/rest_api/types/span_user_defined_metric_python_code_public.py +20 -0
  180. opik/rest_api/types/span_user_defined_metric_python_code_write.py +20 -0
  181. opik/types.py +36 -0
  182. opik/validation/chat_prompt_messages.py +241 -0
  183. opik/validation/feedback_score.py +3 -3
  184. opik/validation/validator.py +28 -0
  185. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/METADATA +5 -5
  186. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/RECORD +190 -141
  187. opik/cli/export.py +0 -791
  188. opik/cli/import_command.py +0 -575
  189. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/WHEEL +0 -0
  190. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/entry_points.txt +0 -0
  191. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/licenses/LICENSE +0 -0
  192. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/top_level.txt +0 -0
@@ -15,6 +15,7 @@ from ..errors.bad_request_error import BadRequestError
15
15
  from ..errors.conflict_error import ConflictError
16
16
  from ..errors.not_found_error import NotFoundError
17
17
  from ..types.dataset_expansion_response import DatasetExpansionResponse
18
+ from ..types.dataset_item_changes_public import DatasetItemChangesPublic
18
19
  from ..types.dataset_item_filter import DatasetItemFilter
19
20
  from ..types.dataset_item_page_compare import DatasetItemPageCompare
20
21
  from ..types.dataset_item_page_public import DatasetItemPagePublic
@@ -43,12 +44,108 @@ class RawDatasetsClient:
43
44
  def __init__(self, *, client_wrapper: SyncClientWrapper):
44
45
  self._client_wrapper = client_wrapper
45
46
 
47
+ def apply_dataset_item_changes(
48
+ self,
49
+ id: str,
50
+ *,
51
+ request: DatasetItemChangesPublic,
52
+ override: typing.Optional[bool] = None,
53
+ request_options: typing.Optional[RequestOptions] = None,
54
+ ) -> HttpResponse[DatasetVersionPublic]:
55
+ """
56
+ Apply delta changes (add, edit, delete) to a dataset version with conflict detection.
57
+
58
+ This endpoint:
59
+ - Creates a new version with the applied changes
60
+ - Validates that baseVersion matches the latest version (unless override=true)
61
+ - Returns 409 Conflict if baseVersion is stale and override is not set
62
+
63
+ Use `override=true` query parameter to force version creation even with stale baseVersion.
64
+
65
+ Parameters
66
+ ----------
67
+ id : str
68
+
69
+ request : DatasetItemChangesPublic
70
+
71
+ override : typing.Optional[bool]
72
+
73
+ request_options : typing.Optional[RequestOptions]
74
+ Request-specific configuration.
75
+
76
+ Returns
77
+ -------
78
+ HttpResponse[DatasetVersionPublic]
79
+ Version created successfully
80
+ """
81
+ _response = self._client_wrapper.httpx_client.request(
82
+ f"v1/private/datasets/{jsonable_encoder(id)}/items/changes",
83
+ method="POST",
84
+ params={
85
+ "override": override,
86
+ },
87
+ json=request,
88
+ headers={
89
+ "content-type": "application/json",
90
+ },
91
+ request_options=request_options,
92
+ omit=OMIT,
93
+ )
94
+ try:
95
+ if 200 <= _response.status_code < 300:
96
+ _data = typing.cast(
97
+ DatasetVersionPublic,
98
+ parse_obj_as(
99
+ type_=DatasetVersionPublic, # type: ignore
100
+ object_=_response.json(),
101
+ ),
102
+ )
103
+ return HttpResponse(response=_response, data=_data)
104
+ if _response.status_code == 400:
105
+ raise BadRequestError(
106
+ headers=dict(_response.headers),
107
+ body=typing.cast(
108
+ typing.Optional[typing.Any],
109
+ parse_obj_as(
110
+ type_=typing.Optional[typing.Any], # type: ignore
111
+ object_=_response.json(),
112
+ ),
113
+ ),
114
+ )
115
+ if _response.status_code == 404:
116
+ raise NotFoundError(
117
+ headers=dict(_response.headers),
118
+ body=typing.cast(
119
+ typing.Optional[typing.Any],
120
+ parse_obj_as(
121
+ type_=typing.Optional[typing.Any], # type: ignore
122
+ object_=_response.json(),
123
+ ),
124
+ ),
125
+ )
126
+ if _response.status_code == 409:
127
+ raise ConflictError(
128
+ headers=dict(_response.headers),
129
+ body=typing.cast(
130
+ typing.Optional[typing.Any],
131
+ parse_obj_as(
132
+ type_=typing.Optional[typing.Any], # type: ignore
133
+ object_=_response.json(),
134
+ ),
135
+ ),
136
+ )
137
+ _response_json = _response.json()
138
+ except JSONDecodeError:
139
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
140
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
141
+
46
142
  def batch_update_dataset_items(
47
143
  self,
48
144
  *,
49
145
  update: DatasetItemUpdate,
50
146
  ids: typing.Optional[typing.Sequence[str]] = OMIT,
51
147
  filters: typing.Optional[typing.Sequence[DatasetItemFilter]] = OMIT,
148
+ dataset_id: typing.Optional[str] = OMIT,
52
149
  merge_tags: typing.Optional[bool] = OMIT,
53
150
  request_options: typing.Optional[RequestOptions] = None,
54
151
  ) -> HttpResponse[None]:
@@ -64,6 +161,9 @@ class RawDatasetsClient:
64
161
 
65
162
  filters : typing.Optional[typing.Sequence[DatasetItemFilter]]
66
163
 
164
+ dataset_id : typing.Optional[str]
165
+ Dataset ID. Required when using 'filters', optional when using 'ids'.
166
+
67
167
  merge_tags : typing.Optional[bool]
68
168
  If true, merge tags with existing tags instead of replacing them. Default: false. When using 'filters', this is automatically set to true.
69
169
 
@@ -82,6 +182,7 @@ class RawDatasetsClient:
82
182
  "filters": convert_and_respect_annotation_metadata(
83
183
  object_=filters, annotation=typing.Sequence[DatasetItemFilter], direction="write"
84
184
  ),
185
+ "dataset_id": dataset_id,
85
186
  "update": convert_and_respect_annotation_metadata(
86
187
  object_=update, annotation=DatasetItemUpdate, direction="write"
87
188
  ),
@@ -246,6 +347,7 @@ class RawDatasetsClient:
246
347
  items: typing.Sequence[DatasetItemWrite],
247
348
  dataset_name: typing.Optional[str] = OMIT,
248
349
  dataset_id: typing.Optional[str] = OMIT,
350
+ batch_group_id: typing.Optional[str] = OMIT,
249
351
  request_options: typing.Optional[RequestOptions] = None,
250
352
  ) -> HttpResponse[None]:
251
353
  """
@@ -261,6 +363,9 @@ class RawDatasetsClient:
261
363
  dataset_id : typing.Optional[str]
262
364
  If null, dataset_name must be provided
263
365
 
366
+ batch_group_id : typing.Optional[str]
367
+ Optional batch group ID to group multiple batches into a single dataset version. If null, mutates the latest version instead of creating a new one.
368
+
264
369
  request_options : typing.Optional[RequestOptions]
265
370
  Request-specific configuration.
266
371
 
@@ -277,6 +382,7 @@ class RawDatasetsClient:
277
382
  "items": convert_and_respect_annotation_metadata(
278
383
  object_=items, annotation=typing.Sequence[DatasetItemWrite], direction="write"
279
384
  ),
385
+ "batch_group_id": batch_group_id,
280
386
  },
281
387
  headers={
282
388
  "content-type": "application/json",
@@ -615,14 +721,34 @@ class RawDatasetsClient:
615
721
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
616
722
 
617
723
  def delete_dataset_items(
618
- self, *, item_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
724
+ self,
725
+ *,
726
+ item_ids: typing.Optional[typing.Sequence[str]] = OMIT,
727
+ dataset_id: typing.Optional[str] = OMIT,
728
+ filters: typing.Optional[typing.Sequence[DatasetItemFilter]] = OMIT,
729
+ batch_group_id: typing.Optional[str] = OMIT,
730
+ request_options: typing.Optional[RequestOptions] = None,
619
731
  ) -> HttpResponse[None]:
620
732
  """
621
- Delete dataset items
733
+ Delete dataset items using one of two modes:
734
+ 1. **Delete by IDs**: Provide 'item_ids' to delete specific items by their IDs
735
+ 2. **Delete by filters**: Provide 'dataset_id' with optional 'filters' to delete items matching criteria
736
+
737
+ When using filters, an empty 'filters' array will delete all items in the specified dataset.
622
738
 
623
739
  Parameters
624
740
  ----------
625
- item_ids : typing.Sequence[str]
741
+ item_ids : typing.Optional[typing.Sequence[str]]
742
+ List of dataset item IDs to delete (max 1000). Use this to delete specific items by their IDs. Mutually exclusive with 'dataset_id' and 'filters'.
743
+
744
+ dataset_id : typing.Optional[str]
745
+ Dataset ID to scope the deletion. Required when using 'filters'. Mutually exclusive with 'item_ids'.
746
+
747
+ filters : typing.Optional[typing.Sequence[DatasetItemFilter]]
748
+ Filters to select dataset items to delete within the specified dataset. Must be used with 'dataset_id'. Mutually exclusive with 'item_ids'. Empty array means 'delete all items in the dataset'.
749
+
750
+ batch_group_id : typing.Optional[str]
751
+ Optional batch group ID to group multiple delete operations into a single dataset version. If null, mutates the latest version instead of creating a new one.
626
752
 
627
753
  request_options : typing.Optional[RequestOptions]
628
754
  Request-specific configuration.
@@ -636,6 +762,11 @@ class RawDatasetsClient:
636
762
  method="POST",
637
763
  json={
638
764
  "item_ids": item_ids,
765
+ "dataset_id": dataset_id,
766
+ "filters": convert_and_respect_annotation_metadata(
767
+ object_=filters, annotation=typing.Sequence[DatasetItemFilter], direction="write"
768
+ ),
769
+ "batch_group_id": batch_group_id,
639
770
  },
640
771
  headers={
641
772
  "content-type": "application/json",
@@ -646,6 +777,17 @@ class RawDatasetsClient:
646
777
  try:
647
778
  if 200 <= _response.status_code < 300:
648
779
  return HttpResponse(response=_response, data=None)
780
+ if _response.status_code == 400:
781
+ raise BadRequestError(
782
+ headers=dict(_response.headers),
783
+ body=typing.cast(
784
+ typing.Optional[typing.Any],
785
+ parse_obj_as(
786
+ type_=typing.Optional[typing.Any], # type: ignore
787
+ object_=_response.json(),
788
+ ),
789
+ ),
790
+ )
649
791
  _response_json = _response.json()
650
792
  except JSONDecodeError:
651
793
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
@@ -1156,6 +1298,7 @@ class RawDatasetsClient:
1156
1298
  dataset_name: str,
1157
1299
  last_retrieved_id: typing.Optional[str] = OMIT,
1158
1300
  steam_limit: typing.Optional[int] = OMIT,
1301
+ dataset_version: typing.Optional[str] = OMIT,
1159
1302
  request_options: typing.Optional[RequestOptions] = None,
1160
1303
  ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
1161
1304
  """
@@ -1169,6 +1312,8 @@ class RawDatasetsClient:
1169
1312
 
1170
1313
  steam_limit : typing.Optional[int]
1171
1314
 
1315
+ dataset_version : typing.Optional[str]
1316
+
1172
1317
  request_options : typing.Optional[RequestOptions]
1173
1318
  Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
1174
1319
 
@@ -1184,6 +1329,7 @@ class RawDatasetsClient:
1184
1329
  "dataset_name": dataset_name,
1185
1330
  "last_retrieved_id": last_retrieved_id,
1186
1331
  "steam_limit": steam_limit,
1332
+ "dataset_version": dataset_version,
1187
1333
  },
1188
1334
  headers={
1189
1335
  "content-type": "application/json",
@@ -1332,6 +1478,40 @@ class RawDatasetsClient:
1332
1478
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1333
1479
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1334
1480
 
1481
+ def delete_version_tag(
1482
+ self, version_hash: str, tag: str, id: str, *, request_options: typing.Optional[RequestOptions] = None
1483
+ ) -> HttpResponse[None]:
1484
+ """
1485
+ Remove a tag from a dataset version. The version itself is not deleted, only the tag reference.
1486
+
1487
+ Parameters
1488
+ ----------
1489
+ version_hash : str
1490
+
1491
+ tag : str
1492
+
1493
+ id : str
1494
+
1495
+ request_options : typing.Optional[RequestOptions]
1496
+ Request-specific configuration.
1497
+
1498
+ Returns
1499
+ -------
1500
+ HttpResponse[None]
1501
+ """
1502
+ _response = self._client_wrapper.httpx_client.request(
1503
+ f"v1/private/datasets/{jsonable_encoder(id)}/versions/{jsonable_encoder(version_hash)}/tags/{jsonable_encoder(tag)}",
1504
+ method="DELETE",
1505
+ request_options=request_options,
1506
+ )
1507
+ try:
1508
+ if 200 <= _response.status_code < 300:
1509
+ return HttpResponse(response=_response, data=None)
1510
+ _response_json = _response.json()
1511
+ except JSONDecodeError:
1512
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1513
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1514
+
1335
1515
  def list_dataset_versions(
1336
1516
  self,
1337
1517
  id: str,
@@ -1394,45 +1574,32 @@ class RawDatasetsClient:
1394
1574
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1395
1575
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1396
1576
 
1397
- def create_dataset_version(
1398
- self,
1399
- id: str,
1400
- *,
1401
- tags: typing.Optional[typing.Sequence[str]] = OMIT,
1402
- change_description: typing.Optional[str] = OMIT,
1403
- metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
1404
- request_options: typing.Optional[RequestOptions] = None,
1405
- ) -> HttpResponse[None]:
1577
+ def restore_dataset_version(
1578
+ self, id: str, *, version_ref: str, request_options: typing.Optional[RequestOptions] = None
1579
+ ) -> HttpResponse[DatasetVersionPublic]:
1406
1580
  """
1407
- Create a new immutable version of the dataset by snapshotting the current state
1581
+ Restores the dataset to a previous version state by creating a new version with items copied from the specified version. If the version is already the latest, returns it as-is (no-op).
1408
1582
 
1409
1583
  Parameters
1410
1584
  ----------
1411
1585
  id : str
1412
1586
 
1413
- tags : typing.Optional[typing.Sequence[str]]
1414
- Optional list of tags for this version
1415
-
1416
- change_description : typing.Optional[str]
1417
- Optional description of changes in this version
1418
-
1419
- metadata : typing.Optional[typing.Dict[str, str]]
1420
- Optional user-defined metadata
1587
+ version_ref : str
1588
+ Version hash or tag to restore from
1421
1589
 
1422
1590
  request_options : typing.Optional[RequestOptions]
1423
1591
  Request-specific configuration.
1424
1592
 
1425
1593
  Returns
1426
1594
  -------
1427
- HttpResponse[None]
1595
+ HttpResponse[DatasetVersionPublic]
1596
+ Version restored successfully
1428
1597
  """
1429
1598
  _response = self._client_wrapper.httpx_client.request(
1430
- f"v1/private/datasets/{jsonable_encoder(id)}/versions",
1599
+ f"v1/private/datasets/{jsonable_encoder(id)}/versions/restore",
1431
1600
  method="POST",
1432
1601
  json={
1433
- "tags": tags,
1434
- "change_description": change_description,
1435
- "metadata": metadata,
1602
+ "version_ref": version_ref,
1436
1603
  },
1437
1604
  headers={
1438
1605
  "content-type": "application/json",
@@ -1442,20 +1609,16 @@ class RawDatasetsClient:
1442
1609
  )
1443
1610
  try:
1444
1611
  if 200 <= _response.status_code < 300:
1445
- return HttpResponse(response=_response, data=None)
1446
- if _response.status_code == 400:
1447
- raise BadRequestError(
1448
- headers=dict(_response.headers),
1449
- body=typing.cast(
1450
- typing.Optional[typing.Any],
1451
- parse_obj_as(
1452
- type_=typing.Optional[typing.Any], # type: ignore
1453
- object_=_response.json(),
1454
- ),
1612
+ _data = typing.cast(
1613
+ DatasetVersionPublic,
1614
+ parse_obj_as(
1615
+ type_=DatasetVersionPublic, # type: ignore
1616
+ object_=_response.json(),
1455
1617
  ),
1456
1618
  )
1457
- if _response.status_code == 409:
1458
- raise ConflictError(
1619
+ return HttpResponse(response=_response, data=_data)
1620
+ if _response.status_code == 404:
1621
+ raise NotFoundError(
1459
1622
  headers=dict(_response.headers),
1460
1623
  body=typing.cast(
1461
1624
  typing.Optional[typing.Any],
@@ -1470,52 +1633,29 @@ class RawDatasetsClient:
1470
1633
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1471
1634
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1472
1635
 
1473
- def delete_version_tag(
1474
- self, version_hash: str, tag: str, id: str, *, request_options: typing.Optional[RequestOptions] = None
1475
- ) -> HttpResponse[None]:
1636
+ def update_dataset_version(
1637
+ self,
1638
+ version_hash: str,
1639
+ id: str,
1640
+ *,
1641
+ change_description: typing.Optional[str] = OMIT,
1642
+ tags_to_add: typing.Optional[typing.Sequence[str]] = OMIT,
1643
+ request_options: typing.Optional[RequestOptions] = None,
1644
+ ) -> HttpResponse[DatasetVersionPublic]:
1476
1645
  """
1477
- Remove a tag from a dataset version. The version itself is not deleted, only the tag reference.
1646
+ Update a dataset version's change_description and/or add new tags
1478
1647
 
1479
1648
  Parameters
1480
1649
  ----------
1481
1650
  version_hash : str
1482
1651
 
1483
- tag : str
1484
-
1485
1652
  id : str
1486
1653
 
1487
- request_options : typing.Optional[RequestOptions]
1488
- Request-specific configuration.
1489
-
1490
- Returns
1491
- -------
1492
- HttpResponse[None]
1493
- """
1494
- _response = self._client_wrapper.httpx_client.request(
1495
- f"v1/private/datasets/{jsonable_encoder(id)}/versions/{jsonable_encoder(version_hash)}/tags/{jsonable_encoder(tag)}",
1496
- method="DELETE",
1497
- request_options=request_options,
1498
- )
1499
- try:
1500
- if 200 <= _response.status_code < 300:
1501
- return HttpResponse(response=_response, data=None)
1502
- _response_json = _response.json()
1503
- except JSONDecodeError:
1504
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1505
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1506
-
1507
- def restore_dataset_version(
1508
- self, id: str, *, version_ref: str, request_options: typing.Optional[RequestOptions] = None
1509
- ) -> HttpResponse[DatasetVersionPublic]:
1510
- """
1511
- Restores the dataset to a previous version state. All draft items are replaced with items from the specified version. If the version is not the latest, a new version snapshot is created. If the version is the latest, only draft items are replaced (revert functionality).
1512
-
1513
- Parameters
1514
- ----------
1515
- id : str
1654
+ change_description : typing.Optional[str]
1655
+ Optional description of changes in this version
1516
1656
 
1517
- version_ref : str
1518
- Version hash or tag to restore from
1657
+ tags_to_add : typing.Optional[typing.Sequence[str]]
1658
+ Optional list of tags to add to this version
1519
1659
 
1520
1660
  request_options : typing.Optional[RequestOptions]
1521
1661
  Request-specific configuration.
@@ -1523,13 +1663,14 @@ class RawDatasetsClient:
1523
1663
  Returns
1524
1664
  -------
1525
1665
  HttpResponse[DatasetVersionPublic]
1526
- Version restored successfully
1666
+ Version updated successfully
1527
1667
  """
1528
1668
  _response = self._client_wrapper.httpx_client.request(
1529
- f"v1/private/datasets/{jsonable_encoder(id)}/versions/restore",
1530
- method="POST",
1669
+ f"v1/private/datasets/{jsonable_encoder(id)}/versions/hash/{jsonable_encoder(version_hash)}",
1670
+ method="PATCH",
1531
1671
  json={
1532
- "version_ref": version_ref,
1672
+ "change_description": change_description,
1673
+ "tags_to_add": tags_to_add,
1533
1674
  },
1534
1675
  headers={
1535
1676
  "content-type": "application/json",
@@ -1547,6 +1688,17 @@ class RawDatasetsClient:
1547
1688
  ),
1548
1689
  )
1549
1690
  return HttpResponse(response=_response, data=_data)
1691
+ if _response.status_code == 400:
1692
+ raise BadRequestError(
1693
+ headers=dict(_response.headers),
1694
+ body=typing.cast(
1695
+ typing.Optional[typing.Any],
1696
+ parse_obj_as(
1697
+ type_=typing.Optional[typing.Any], # type: ignore
1698
+ object_=_response.json(),
1699
+ ),
1700
+ ),
1701
+ )
1550
1702
  if _response.status_code == 404:
1551
1703
  raise NotFoundError(
1552
1704
  headers=dict(_response.headers),
@@ -1558,50 +1710,68 @@ class RawDatasetsClient:
1558
1710
  ),
1559
1711
  ),
1560
1712
  )
1713
+ if _response.status_code == 409:
1714
+ raise ConflictError(
1715
+ headers=dict(_response.headers),
1716
+ body=typing.cast(
1717
+ typing.Optional[typing.Any],
1718
+ parse_obj_as(
1719
+ type_=typing.Optional[typing.Any], # type: ignore
1720
+ object_=_response.json(),
1721
+ ),
1722
+ ),
1723
+ )
1561
1724
  _response_json = _response.json()
1562
1725
  except JSONDecodeError:
1563
1726
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1564
1727
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1565
1728
 
1566
- def update_dataset_version(
1729
+
1730
+ class AsyncRawDatasetsClient:
1731
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
1732
+ self._client_wrapper = client_wrapper
1733
+
1734
+ async def apply_dataset_item_changes(
1567
1735
  self,
1568
- version_hash: str,
1569
1736
  id: str,
1570
1737
  *,
1571
- change_description: typing.Optional[str] = OMIT,
1572
- tags_to_add: typing.Optional[typing.Sequence[str]] = OMIT,
1738
+ request: DatasetItemChangesPublic,
1739
+ override: typing.Optional[bool] = None,
1573
1740
  request_options: typing.Optional[RequestOptions] = None,
1574
- ) -> HttpResponse[DatasetVersionPublic]:
1741
+ ) -> AsyncHttpResponse[DatasetVersionPublic]:
1575
1742
  """
1576
- Update a dataset version's change_description and/or add new tags
1743
+ Apply delta changes (add, edit, delete) to a dataset version with conflict detection.
1744
+
1745
+ This endpoint:
1746
+ - Creates a new version with the applied changes
1747
+ - Validates that baseVersion matches the latest version (unless override=true)
1748
+ - Returns 409 Conflict if baseVersion is stale and override is not set
1749
+
1750
+ Use `override=true` query parameter to force version creation even with stale baseVersion.
1577
1751
 
1578
1752
  Parameters
1579
1753
  ----------
1580
- version_hash : str
1581
-
1582
1754
  id : str
1583
1755
 
1584
- change_description : typing.Optional[str]
1585
- Optional description of changes in this version
1756
+ request : DatasetItemChangesPublic
1586
1757
 
1587
- tags_to_add : typing.Optional[typing.Sequence[str]]
1588
- Optional list of tags to add to this version
1758
+ override : typing.Optional[bool]
1589
1759
 
1590
1760
  request_options : typing.Optional[RequestOptions]
1591
1761
  Request-specific configuration.
1592
1762
 
1593
1763
  Returns
1594
1764
  -------
1595
- HttpResponse[DatasetVersionPublic]
1596
- Version updated successfully
1765
+ AsyncHttpResponse[DatasetVersionPublic]
1766
+ Version created successfully
1597
1767
  """
1598
- _response = self._client_wrapper.httpx_client.request(
1599
- f"v1/private/datasets/{jsonable_encoder(id)}/versions/hash/{jsonable_encoder(version_hash)}",
1600
- method="PATCH",
1601
- json={
1602
- "change_description": change_description,
1603
- "tags_to_add": tags_to_add,
1768
+ _response = await self._client_wrapper.httpx_client.request(
1769
+ f"v1/private/datasets/{jsonable_encoder(id)}/items/changes",
1770
+ method="POST",
1771
+ params={
1772
+ "override": override,
1604
1773
  },
1774
+ json=request,
1605
1775
  headers={
1606
1776
  "content-type": "application/json",
1607
1777
  },
@@ -1617,7 +1787,7 @@ class RawDatasetsClient:
1617
1787
  object_=_response.json(),
1618
1788
  ),
1619
1789
  )
1620
- return HttpResponse(response=_response, data=_data)
1790
+ return AsyncHttpResponse(response=_response, data=_data)
1621
1791
  if _response.status_code == 400:
1622
1792
  raise BadRequestError(
1623
1793
  headers=dict(_response.headers),
@@ -1656,17 +1826,13 @@ class RawDatasetsClient:
1656
1826
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1657
1827
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1658
1828
 
1659
-
1660
- class AsyncRawDatasetsClient:
1661
- def __init__(self, *, client_wrapper: AsyncClientWrapper):
1662
- self._client_wrapper = client_wrapper
1663
-
1664
1829
  async def batch_update_dataset_items(
1665
1830
  self,
1666
1831
  *,
1667
1832
  update: DatasetItemUpdate,
1668
1833
  ids: typing.Optional[typing.Sequence[str]] = OMIT,
1669
1834
  filters: typing.Optional[typing.Sequence[DatasetItemFilter]] = OMIT,
1835
+ dataset_id: typing.Optional[str] = OMIT,
1670
1836
  merge_tags: typing.Optional[bool] = OMIT,
1671
1837
  request_options: typing.Optional[RequestOptions] = None,
1672
1838
  ) -> AsyncHttpResponse[None]:
@@ -1682,6 +1848,9 @@ class AsyncRawDatasetsClient:
1682
1848
 
1683
1849
  filters : typing.Optional[typing.Sequence[DatasetItemFilter]]
1684
1850
 
1851
+ dataset_id : typing.Optional[str]
1852
+ Dataset ID. Required when using 'filters', optional when using 'ids'.
1853
+
1685
1854
  merge_tags : typing.Optional[bool]
1686
1855
  If true, merge tags with existing tags instead of replacing them. Default: false. When using 'filters', this is automatically set to true.
1687
1856
 
@@ -1700,6 +1869,7 @@ class AsyncRawDatasetsClient:
1700
1869
  "filters": convert_and_respect_annotation_metadata(
1701
1870
  object_=filters, annotation=typing.Sequence[DatasetItemFilter], direction="write"
1702
1871
  ),
1872
+ "dataset_id": dataset_id,
1703
1873
  "update": convert_and_respect_annotation_metadata(
1704
1874
  object_=update, annotation=DatasetItemUpdate, direction="write"
1705
1875
  ),
@@ -1864,6 +2034,7 @@ class AsyncRawDatasetsClient:
1864
2034
  items: typing.Sequence[DatasetItemWrite],
1865
2035
  dataset_name: typing.Optional[str] = OMIT,
1866
2036
  dataset_id: typing.Optional[str] = OMIT,
2037
+ batch_group_id: typing.Optional[str] = OMIT,
1867
2038
  request_options: typing.Optional[RequestOptions] = None,
1868
2039
  ) -> AsyncHttpResponse[None]:
1869
2040
  """
@@ -1879,6 +2050,9 @@ class AsyncRawDatasetsClient:
1879
2050
  dataset_id : typing.Optional[str]
1880
2051
  If null, dataset_name must be provided
1881
2052
 
2053
+ batch_group_id : typing.Optional[str]
2054
+ Optional batch group ID to group multiple batches into a single dataset version. If null, mutates the latest version instead of creating a new one.
2055
+
1882
2056
  request_options : typing.Optional[RequestOptions]
1883
2057
  Request-specific configuration.
1884
2058
 
@@ -1895,6 +2069,7 @@ class AsyncRawDatasetsClient:
1895
2069
  "items": convert_and_respect_annotation_metadata(
1896
2070
  object_=items, annotation=typing.Sequence[DatasetItemWrite], direction="write"
1897
2071
  ),
2072
+ "batch_group_id": batch_group_id,
1898
2073
  },
1899
2074
  headers={
1900
2075
  "content-type": "application/json",
@@ -2235,14 +2410,34 @@ class AsyncRawDatasetsClient:
2235
2410
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2236
2411
 
2237
2412
  async def delete_dataset_items(
2238
- self, *, item_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
2413
+ self,
2414
+ *,
2415
+ item_ids: typing.Optional[typing.Sequence[str]] = OMIT,
2416
+ dataset_id: typing.Optional[str] = OMIT,
2417
+ filters: typing.Optional[typing.Sequence[DatasetItemFilter]] = OMIT,
2418
+ batch_group_id: typing.Optional[str] = OMIT,
2419
+ request_options: typing.Optional[RequestOptions] = None,
2239
2420
  ) -> AsyncHttpResponse[None]:
2240
2421
  """
2241
- Delete dataset items
2422
+ Delete dataset items using one of two modes:
2423
+ 1. **Delete by IDs**: Provide 'item_ids' to delete specific items by their IDs
2424
+ 2. **Delete by filters**: Provide 'dataset_id' with optional 'filters' to delete items matching criteria
2425
+
2426
+ When using filters, an empty 'filters' array will delete all items in the specified dataset.
2242
2427
 
2243
2428
  Parameters
2244
2429
  ----------
2245
- item_ids : typing.Sequence[str]
2430
+ item_ids : typing.Optional[typing.Sequence[str]]
2431
+ List of dataset item IDs to delete (max 1000). Use this to delete specific items by their IDs. Mutually exclusive with 'dataset_id' and 'filters'.
2432
+
2433
+ dataset_id : typing.Optional[str]
2434
+ Dataset ID to scope the deletion. Required when using 'filters'. Mutually exclusive with 'item_ids'.
2435
+
2436
+ filters : typing.Optional[typing.Sequence[DatasetItemFilter]]
2437
+ Filters to select dataset items to delete within the specified dataset. Must be used with 'dataset_id'. Mutually exclusive with 'item_ids'. Empty array means 'delete all items in the dataset'.
2438
+
2439
+ batch_group_id : typing.Optional[str]
2440
+ Optional batch group ID to group multiple delete operations into a single dataset version. If null, mutates the latest version instead of creating a new one.
2246
2441
 
2247
2442
  request_options : typing.Optional[RequestOptions]
2248
2443
  Request-specific configuration.
@@ -2256,6 +2451,11 @@ class AsyncRawDatasetsClient:
2256
2451
  method="POST",
2257
2452
  json={
2258
2453
  "item_ids": item_ids,
2454
+ "dataset_id": dataset_id,
2455
+ "filters": convert_and_respect_annotation_metadata(
2456
+ object_=filters, annotation=typing.Sequence[DatasetItemFilter], direction="write"
2457
+ ),
2458
+ "batch_group_id": batch_group_id,
2259
2459
  },
2260
2460
  headers={
2261
2461
  "content-type": "application/json",
@@ -2266,6 +2466,17 @@ class AsyncRawDatasetsClient:
2266
2466
  try:
2267
2467
  if 200 <= _response.status_code < 300:
2268
2468
  return AsyncHttpResponse(response=_response, data=None)
2469
+ if _response.status_code == 400:
2470
+ raise BadRequestError(
2471
+ headers=dict(_response.headers),
2472
+ body=typing.cast(
2473
+ typing.Optional[typing.Any],
2474
+ parse_obj_as(
2475
+ type_=typing.Optional[typing.Any], # type: ignore
2476
+ object_=_response.json(),
2477
+ ),
2478
+ ),
2479
+ )
2269
2480
  _response_json = _response.json()
2270
2481
  except JSONDecodeError:
2271
2482
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
@@ -2776,6 +2987,7 @@ class AsyncRawDatasetsClient:
2776
2987
  dataset_name: str,
2777
2988
  last_retrieved_id: typing.Optional[str] = OMIT,
2778
2989
  steam_limit: typing.Optional[int] = OMIT,
2990
+ dataset_version: typing.Optional[str] = OMIT,
2779
2991
  request_options: typing.Optional[RequestOptions] = None,
2780
2992
  ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
2781
2993
  """
@@ -2789,6 +3001,8 @@ class AsyncRawDatasetsClient:
2789
3001
 
2790
3002
  steam_limit : typing.Optional[int]
2791
3003
 
3004
+ dataset_version : typing.Optional[str]
3005
+
2792
3006
  request_options : typing.Optional[RequestOptions]
2793
3007
  Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
2794
3008
 
@@ -2804,6 +3018,7 @@ class AsyncRawDatasetsClient:
2804
3018
  "dataset_name": dataset_name,
2805
3019
  "last_retrieved_id": last_retrieved_id,
2806
3020
  "steam_limit": steam_limit,
3021
+ "dataset_version": dataset_version,
2807
3022
  },
2808
3023
  headers={
2809
3024
  "content-type": "application/json",
@@ -2953,130 +3168,88 @@ class AsyncRawDatasetsClient:
2953
3168
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2954
3169
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2955
3170
 
2956
- async def list_dataset_versions(
2957
- self,
2958
- id: str,
2959
- *,
2960
- page: typing.Optional[int] = None,
2961
- size: typing.Optional[int] = None,
2962
- request_options: typing.Optional[RequestOptions] = None,
2963
- ) -> AsyncHttpResponse[DatasetVersionPagePublic]:
3171
+ async def delete_version_tag(
3172
+ self, version_hash: str, tag: str, id: str, *, request_options: typing.Optional[RequestOptions] = None
3173
+ ) -> AsyncHttpResponse[None]:
2964
3174
  """
2965
- Get paginated list of versions for a dataset, ordered by creation time (newest first)
3175
+ Remove a tag from a dataset version. The version itself is not deleted, only the tag reference.
2966
3176
 
2967
3177
  Parameters
2968
3178
  ----------
2969
- id : str
3179
+ version_hash : str
2970
3180
 
2971
- page : typing.Optional[int]
3181
+ tag : str
2972
3182
 
2973
- size : typing.Optional[int]
3183
+ id : str
2974
3184
 
2975
3185
  request_options : typing.Optional[RequestOptions]
2976
3186
  Request-specific configuration.
2977
3187
 
2978
3188
  Returns
2979
3189
  -------
2980
- AsyncHttpResponse[DatasetVersionPagePublic]
2981
- Dataset versions
3190
+ AsyncHttpResponse[None]
2982
3191
  """
2983
3192
  _response = await self._client_wrapper.httpx_client.request(
2984
- f"v1/private/datasets/{jsonable_encoder(id)}/versions",
2985
- method="GET",
2986
- params={
2987
- "page": page,
2988
- "size": size,
2989
- },
3193
+ f"v1/private/datasets/{jsonable_encoder(id)}/versions/{jsonable_encoder(version_hash)}/tags/{jsonable_encoder(tag)}",
3194
+ method="DELETE",
2990
3195
  request_options=request_options,
2991
3196
  )
2992
3197
  try:
2993
3198
  if 200 <= _response.status_code < 300:
2994
- _data = typing.cast(
2995
- DatasetVersionPagePublic,
2996
- parse_obj_as(
2997
- type_=DatasetVersionPagePublic, # type: ignore
2998
- object_=_response.json(),
2999
- ),
3000
- )
3001
- return AsyncHttpResponse(response=_response, data=_data)
3002
- if _response.status_code == 400:
3003
- raise BadRequestError(
3004
- headers=dict(_response.headers),
3005
- body=typing.cast(
3006
- typing.Optional[typing.Any],
3007
- parse_obj_as(
3008
- type_=typing.Optional[typing.Any], # type: ignore
3009
- object_=_response.json(),
3010
- ),
3011
- ),
3012
- )
3199
+ return AsyncHttpResponse(response=_response, data=None)
3013
3200
  _response_json = _response.json()
3014
3201
  except JSONDecodeError:
3015
3202
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3016
3203
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3017
3204
 
3018
- async def create_dataset_version(
3205
+ async def list_dataset_versions(
3019
3206
  self,
3020
3207
  id: str,
3021
3208
  *,
3022
- tags: typing.Optional[typing.Sequence[str]] = OMIT,
3023
- change_description: typing.Optional[str] = OMIT,
3024
- metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
3209
+ page: typing.Optional[int] = None,
3210
+ size: typing.Optional[int] = None,
3025
3211
  request_options: typing.Optional[RequestOptions] = None,
3026
- ) -> AsyncHttpResponse[None]:
3212
+ ) -> AsyncHttpResponse[DatasetVersionPagePublic]:
3027
3213
  """
3028
- Create a new immutable version of the dataset by snapshotting the current state
3214
+ Get paginated list of versions for a dataset, ordered by creation time (newest first)
3029
3215
 
3030
3216
  Parameters
3031
3217
  ----------
3032
3218
  id : str
3033
3219
 
3034
- tags : typing.Optional[typing.Sequence[str]]
3035
- Optional list of tags for this version
3036
-
3037
- change_description : typing.Optional[str]
3038
- Optional description of changes in this version
3220
+ page : typing.Optional[int]
3039
3221
 
3040
- metadata : typing.Optional[typing.Dict[str, str]]
3041
- Optional user-defined metadata
3222
+ size : typing.Optional[int]
3042
3223
 
3043
3224
  request_options : typing.Optional[RequestOptions]
3044
3225
  Request-specific configuration.
3045
3226
 
3046
3227
  Returns
3047
3228
  -------
3048
- AsyncHttpResponse[None]
3229
+ AsyncHttpResponse[DatasetVersionPagePublic]
3230
+ Dataset versions
3049
3231
  """
3050
3232
  _response = await self._client_wrapper.httpx_client.request(
3051
3233
  f"v1/private/datasets/{jsonable_encoder(id)}/versions",
3052
- method="POST",
3053
- json={
3054
- "tags": tags,
3055
- "change_description": change_description,
3056
- "metadata": metadata,
3057
- },
3058
- headers={
3059
- "content-type": "application/json",
3234
+ method="GET",
3235
+ params={
3236
+ "page": page,
3237
+ "size": size,
3060
3238
  },
3061
3239
  request_options=request_options,
3062
- omit=OMIT,
3063
3240
  )
3064
3241
  try:
3065
3242
  if 200 <= _response.status_code < 300:
3066
- return AsyncHttpResponse(response=_response, data=None)
3067
- if _response.status_code == 400:
3068
- raise BadRequestError(
3069
- headers=dict(_response.headers),
3070
- body=typing.cast(
3071
- typing.Optional[typing.Any],
3072
- parse_obj_as(
3073
- type_=typing.Optional[typing.Any], # type: ignore
3074
- object_=_response.json(),
3075
- ),
3243
+ _data = typing.cast(
3244
+ DatasetVersionPagePublic,
3245
+ parse_obj_as(
3246
+ type_=DatasetVersionPagePublic, # type: ignore
3247
+ object_=_response.json(),
3076
3248
  ),
3077
3249
  )
3078
- if _response.status_code == 409:
3079
- raise ConflictError(
3250
+ return AsyncHttpResponse(response=_response, data=_data)
3251
+ if _response.status_code == 400:
3252
+ raise BadRequestError(
3080
3253
  headers=dict(_response.headers),
3081
3254
  body=typing.cast(
3082
3255
  typing.Optional[typing.Any],
@@ -3091,45 +3264,11 @@ class AsyncRawDatasetsClient:
3091
3264
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3092
3265
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3093
3266
 
3094
- async def delete_version_tag(
3095
- self, version_hash: str, tag: str, id: str, *, request_options: typing.Optional[RequestOptions] = None
3096
- ) -> AsyncHttpResponse[None]:
3097
- """
3098
- Remove a tag from a dataset version. The version itself is not deleted, only the tag reference.
3099
-
3100
- Parameters
3101
- ----------
3102
- version_hash : str
3103
-
3104
- tag : str
3105
-
3106
- id : str
3107
-
3108
- request_options : typing.Optional[RequestOptions]
3109
- Request-specific configuration.
3110
-
3111
- Returns
3112
- -------
3113
- AsyncHttpResponse[None]
3114
- """
3115
- _response = await self._client_wrapper.httpx_client.request(
3116
- f"v1/private/datasets/{jsonable_encoder(id)}/versions/{jsonable_encoder(version_hash)}/tags/{jsonable_encoder(tag)}",
3117
- method="DELETE",
3118
- request_options=request_options,
3119
- )
3120
- try:
3121
- if 200 <= _response.status_code < 300:
3122
- return AsyncHttpResponse(response=_response, data=None)
3123
- _response_json = _response.json()
3124
- except JSONDecodeError:
3125
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3126
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3127
-
3128
3267
  async def restore_dataset_version(
3129
3268
  self, id: str, *, version_ref: str, request_options: typing.Optional[RequestOptions] = None
3130
3269
  ) -> AsyncHttpResponse[DatasetVersionPublic]:
3131
3270
  """
3132
- Restores the dataset to a previous version state. All draft items are replaced with items from the specified version. If the version is not the latest, a new version snapshot is created. If the version is the latest, only draft items are replaced (revert functionality).
3271
+ Restores the dataset to a previous version state by creating a new version with items copied from the specified version. If the version is already the latest, returns it as-is (no-op).
3133
3272
 
3134
3273
  Parameters
3135
3274
  ----------