label-studio-sdk 1.0.8__py3-none-any.whl → 1.0.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 label-studio-sdk might be problematic. Click here for more details.

Files changed (218) hide show
  1. label_studio_sdk/__init__.py +37 -8
  2. label_studio_sdk/_extensions/label_studio_tools/core/utils/io.py +16 -4
  3. label_studio_sdk/_extensions/label_studio_tools/core/utils/json_schema.py +5 -0
  4. label_studio_sdk/_extensions/pager_ext.py +8 -0
  5. label_studio_sdk/actions/client.py +91 -40
  6. label_studio_sdk/actions/types/actions_create_request_filters.py +14 -24
  7. label_studio_sdk/actions/types/actions_create_request_filters_items_item.py +16 -26
  8. label_studio_sdk/actions/types/actions_create_request_filters_items_item_value.py +3 -1
  9. label_studio_sdk/actions/types/actions_create_request_selected_items.py +1 -2
  10. label_studio_sdk/actions/types/actions_create_request_selected_items_excluded.py +15 -25
  11. label_studio_sdk/actions/types/actions_create_request_selected_items_included.py +15 -25
  12. label_studio_sdk/annotations/__init__.py +2 -2
  13. label_studio_sdk/annotations/client.py +278 -104
  14. label_studio_sdk/annotations/types/__init__.py +2 -1
  15. label_studio_sdk/annotations/types/annotations_create_bulk_request_selected_items.py +34 -0
  16. label_studio_sdk/annotations/types/annotations_create_bulk_response_item.py +11 -21
  17. label_studio_sdk/base_client.py +54 -27
  18. label_studio_sdk/client.py +1 -0
  19. label_studio_sdk/comments/client.py +190 -44
  20. label_studio_sdk/converter/converter.py +56 -13
  21. label_studio_sdk/converter/imports/yolo.py +1 -1
  22. label_studio_sdk/converter/utils.py +3 -2
  23. label_studio_sdk/core/__init__.py +21 -4
  24. label_studio_sdk/core/client_wrapper.py +37 -19
  25. label_studio_sdk/core/file.py +37 -8
  26. label_studio_sdk/core/http_client.py +52 -28
  27. label_studio_sdk/core/jsonable_encoder.py +33 -31
  28. label_studio_sdk/core/pagination.py +5 -4
  29. label_studio_sdk/core/pydantic_utilities.py +272 -4
  30. label_studio_sdk/core/query_encoder.py +38 -13
  31. label_studio_sdk/core/request_options.py +3 -0
  32. label_studio_sdk/core/serialization.py +272 -0
  33. label_studio_sdk/errors/__init__.py +3 -1
  34. label_studio_sdk/errors/bad_request_error.py +2 -3
  35. label_studio_sdk/errors/not_found_error.py +9 -0
  36. label_studio_sdk/errors/unauthorized_error.py +9 -0
  37. label_studio_sdk/export_storage/azure/client.py +228 -58
  38. label_studio_sdk/export_storage/azure/types/azure_create_response.py +19 -29
  39. label_studio_sdk/export_storage/azure/types/azure_update_response.py +19 -29
  40. label_studio_sdk/export_storage/client.py +48 -18
  41. label_studio_sdk/export_storage/gcs/client.py +228 -58
  42. label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +19 -29
  43. label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +19 -29
  44. label_studio_sdk/export_storage/local/client.py +222 -56
  45. label_studio_sdk/export_storage/local/types/local_create_response.py +17 -27
  46. label_studio_sdk/export_storage/local/types/local_update_response.py +17 -27
  47. label_studio_sdk/export_storage/redis/client.py +228 -58
  48. label_studio_sdk/export_storage/redis/types/redis_create_response.py +20 -30
  49. label_studio_sdk/export_storage/redis/types/redis_update_response.py +20 -30
  50. label_studio_sdk/export_storage/s3/client.py +228 -58
  51. label_studio_sdk/export_storage/s3/types/s3create_response.py +27 -35
  52. label_studio_sdk/export_storage/s3/types/s3update_response.py +27 -35
  53. label_studio_sdk/export_storage/s3s/client.py +187 -43
  54. label_studio_sdk/export_storage/types/export_storage_list_types_response_item.py +11 -21
  55. label_studio_sdk/files/client.py +172 -56
  56. label_studio_sdk/import_storage/azure/client.py +223 -53
  57. label_studio_sdk/import_storage/azure/types/azure_create_response.py +22 -32
  58. label_studio_sdk/import_storage/azure/types/azure_update_response.py +22 -32
  59. label_studio_sdk/import_storage/client.py +48 -18
  60. label_studio_sdk/import_storage/gcs/client.py +223 -53
  61. label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +22 -32
  62. label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +22 -32
  63. label_studio_sdk/import_storage/local/client.py +223 -53
  64. label_studio_sdk/import_storage/local/types/local_create_response.py +17 -27
  65. label_studio_sdk/import_storage/local/types/local_update_response.py +17 -27
  66. label_studio_sdk/import_storage/redis/client.py +223 -53
  67. label_studio_sdk/import_storage/redis/types/redis_create_response.py +20 -30
  68. label_studio_sdk/import_storage/redis/types/redis_update_response.py +20 -30
  69. label_studio_sdk/import_storage/s3/client.py +223 -53
  70. label_studio_sdk/import_storage/s3/types/s3create_response.py +31 -39
  71. label_studio_sdk/import_storage/s3/types/s3update_response.py +31 -39
  72. label_studio_sdk/import_storage/s3s/client.py +222 -52
  73. label_studio_sdk/import_storage/types/import_storage_list_types_response_item.py +11 -21
  74. label_studio_sdk/jwt_settings/__init__.py +2 -0
  75. label_studio_sdk/jwt_settings/client.py +259 -0
  76. label_studio_sdk/label_interface/control_tags.py +16 -3
  77. label_studio_sdk/label_interface/interface.py +80 -1
  78. label_studio_sdk/label_interface/object_tags.py +2 -2
  79. label_studio_sdk/ml/client.py +280 -78
  80. label_studio_sdk/ml/types/ml_create_response.py +21 -31
  81. label_studio_sdk/ml/types/ml_update_response.py +21 -31
  82. label_studio_sdk/model_providers/client.py +173 -56
  83. label_studio_sdk/predictions/client.py +247 -101
  84. label_studio_sdk/projects/__init__.py +5 -1
  85. label_studio_sdk/projects/client.py +313 -115
  86. label_studio_sdk/projects/client_ext.py +16 -0
  87. label_studio_sdk/projects/exports/__init__.py +3 -0
  88. label_studio_sdk/projects/exports/client.py +447 -296
  89. label_studio_sdk/projects/exports/client_ext.py +200 -0
  90. label_studio_sdk/projects/exports/types/__init__.py +6 -0
  91. label_studio_sdk/projects/exports/types/exports_convert_response.py +24 -0
  92. label_studio_sdk/projects/exports/types/exports_list_formats_response_item.py +44 -0
  93. label_studio_sdk/projects/pauses/__init__.py +2 -0
  94. label_studio_sdk/projects/pauses/client.py +704 -0
  95. label_studio_sdk/projects/types/projects_create_response.py +29 -34
  96. label_studio_sdk/projects/types/projects_import_tasks_response.py +19 -29
  97. label_studio_sdk/projects/types/projects_list_response.py +11 -21
  98. label_studio_sdk/projects/types/projects_update_response.py +34 -34
  99. label_studio_sdk/prompts/client.py +309 -92
  100. label_studio_sdk/prompts/indicators/client.py +67 -23
  101. label_studio_sdk/prompts/runs/client.py +95 -40
  102. label_studio_sdk/prompts/types/prompts_batch_failed_predictions_request_failed_predictions_item.py +14 -24
  103. label_studio_sdk/prompts/types/prompts_batch_failed_predictions_response.py +11 -21
  104. label_studio_sdk/prompts/types/prompts_batch_predictions_request_results_item.py +26 -29
  105. label_studio_sdk/prompts/types/prompts_batch_predictions_response.py +11 -21
  106. label_studio_sdk/prompts/versions/client.py +277 -88
  107. label_studio_sdk/tasks/client.py +263 -90
  108. label_studio_sdk/tasks/types/tasks_list_response.py +15 -25
  109. label_studio_sdk/tokens/__init__.py +2 -0
  110. label_studio_sdk/tokens/client.py +470 -0
  111. label_studio_sdk/tokens/client_ext.py +94 -0
  112. label_studio_sdk/types/__init__.py +20 -6
  113. label_studio_sdk/types/access_token_response.py +22 -0
  114. label_studio_sdk/types/annotation.py +29 -38
  115. label_studio_sdk/types/annotation_filter_options.py +14 -24
  116. label_studio_sdk/types/annotations_dm_field.py +30 -39
  117. label_studio_sdk/types/api_token_response.py +32 -0
  118. label_studio_sdk/types/azure_blob_export_storage.py +28 -37
  119. label_studio_sdk/types/azure_blob_import_storage.py +28 -37
  120. label_studio_sdk/types/base_task.py +30 -39
  121. label_studio_sdk/types/base_task_updated_by.py +3 -1
  122. label_studio_sdk/types/base_user.py +14 -21
  123. label_studio_sdk/types/comment.py +12 -21
  124. label_studio_sdk/types/comment_created_by.py +1 -1
  125. label_studio_sdk/types/converted_format.py +12 -22
  126. label_studio_sdk/types/data_manager_task_serializer.py +31 -40
  127. label_studio_sdk/types/data_manager_task_serializer_annotators_item.py +1 -1
  128. label_studio_sdk/types/data_manager_task_serializer_drafts_item.py +13 -22
  129. label_studio_sdk/types/data_manager_task_serializer_predictions_item.py +15 -24
  130. label_studio_sdk/types/export.py +17 -26
  131. label_studio_sdk/types/export_format.py +25 -0
  132. label_studio_sdk/types/export_snapshot.py +45 -0
  133. label_studio_sdk/types/export_snapshot_status.py +5 -0
  134. label_studio_sdk/types/file_upload.py +11 -21
  135. label_studio_sdk/types/filter.py +16 -26
  136. label_studio_sdk/types/filter_group.py +12 -22
  137. label_studio_sdk/types/gcs_export_storage.py +28 -37
  138. label_studio_sdk/types/gcs_import_storage.py +28 -37
  139. label_studio_sdk/types/inference_run.py +14 -23
  140. label_studio_sdk/types/inference_run_cost_estimate.py +17 -27
  141. label_studio_sdk/types/inference_run_created_by.py +1 -1
  142. label_studio_sdk/types/inference_run_organization.py +1 -1
  143. label_studio_sdk/types/jwt_settings_response.py +32 -0
  144. label_studio_sdk/types/key_indicator_value.py +12 -22
  145. label_studio_sdk/types/key_indicators.py +0 -1
  146. label_studio_sdk/types/key_indicators_item.py +15 -25
  147. label_studio_sdk/types/key_indicators_item_additional_kpis_item.py +13 -23
  148. label_studio_sdk/types/key_indicators_item_extra_kpis_item.py +13 -23
  149. label_studio_sdk/types/local_files_export_storage.py +25 -34
  150. label_studio_sdk/types/local_files_import_storage.py +24 -33
  151. label_studio_sdk/types/ml_backend.py +23 -32
  152. label_studio_sdk/types/model_provider_connection.py +22 -31
  153. label_studio_sdk/types/model_provider_connection_created_by.py +1 -1
  154. label_studio_sdk/types/model_provider_connection_organization.py +1 -1
  155. label_studio_sdk/types/model_provider_connection_provider.py +3 -1
  156. label_studio_sdk/types/pause.py +34 -0
  157. label_studio_sdk/types/pause_paused_by.py +5 -0
  158. label_studio_sdk/types/prediction.py +21 -30
  159. label_studio_sdk/types/project.py +58 -55
  160. label_studio_sdk/types/project_import.py +21 -30
  161. label_studio_sdk/types/project_label_config.py +12 -22
  162. label_studio_sdk/types/prompt.py +24 -32
  163. label_studio_sdk/types/prompt_associated_projects_item.py +6 -0
  164. label_studio_sdk/types/prompt_associated_projects_item_id.py +20 -0
  165. label_studio_sdk/types/prompt_created_by.py +1 -1
  166. label_studio_sdk/types/prompt_organization.py +1 -1
  167. label_studio_sdk/types/prompt_version.py +13 -22
  168. label_studio_sdk/types/prompt_version_created_by.py +1 -1
  169. label_studio_sdk/types/prompt_version_organization.py +1 -1
  170. label_studio_sdk/types/prompt_version_provider.py +3 -1
  171. label_studio_sdk/types/redis_export_storage.py +29 -38
  172. label_studio_sdk/types/redis_import_storage.py +28 -37
  173. label_studio_sdk/types/refined_prompt_response.py +19 -29
  174. label_studio_sdk/types/s3export_storage.py +36 -43
  175. label_studio_sdk/types/s3import_storage.py +37 -44
  176. label_studio_sdk/types/s3s_export_storage.py +26 -33
  177. label_studio_sdk/types/s3s_import_storage.py +35 -42
  178. label_studio_sdk/types/serialization_option.py +12 -22
  179. label_studio_sdk/types/serialization_options.py +18 -28
  180. label_studio_sdk/types/task.py +44 -47
  181. label_studio_sdk/types/task_annotators_item.py +1 -1
  182. label_studio_sdk/types/task_comment_authors_item.py +1 -1
  183. label_studio_sdk/types/task_filter_options.py +15 -25
  184. label_studio_sdk/types/user_simple.py +11 -21
  185. label_studio_sdk/types/view.py +16 -26
  186. label_studio_sdk/types/webhook.py +19 -28
  187. label_studio_sdk/types/webhook_serializer_for_update.py +19 -28
  188. label_studio_sdk/types/workspace.py +22 -31
  189. label_studio_sdk/users/client.py +257 -63
  190. label_studio_sdk/users/types/users_get_token_response.py +12 -22
  191. label_studio_sdk/users/types/users_reset_token_response.py +12 -22
  192. label_studio_sdk/version.py +0 -1
  193. label_studio_sdk/versions/__init__.py +5 -0
  194. label_studio_sdk/versions/client.py +112 -0
  195. label_studio_sdk/versions/types/__init__.py +6 -0
  196. label_studio_sdk/versions/types/versions_get_response.py +73 -0
  197. label_studio_sdk/versions/types/versions_get_response_edition.py +5 -0
  198. label_studio_sdk/views/client.py +219 -52
  199. label_studio_sdk/views/types/views_create_request_data.py +13 -23
  200. label_studio_sdk/views/types/views_create_request_data_filters.py +14 -24
  201. label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +16 -26
  202. label_studio_sdk/views/types/views_create_request_data_filters_items_item_value.py +3 -1
  203. label_studio_sdk/views/types/views_update_request_data.py +13 -23
  204. label_studio_sdk/views/types/views_update_request_data_filters.py +14 -24
  205. label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +16 -26
  206. label_studio_sdk/views/types/views_update_request_data_filters_items_item_value.py +3 -1
  207. label_studio_sdk/webhooks/client.py +191 -61
  208. label_studio_sdk/workspaces/client.py +164 -41
  209. label_studio_sdk/workspaces/members/client.py +109 -31
  210. label_studio_sdk/workspaces/members/types/members_create_response.py +12 -22
  211. label_studio_sdk/workspaces/members/types/members_list_response_item.py +12 -22
  212. {label_studio_sdk-1.0.8.dist-info → label_studio_sdk-1.0.11.dist-info}/METADATA +8 -5
  213. {label_studio_sdk-1.0.8.dist-info → label_studio_sdk-1.0.11.dist-info}/RECORD +215 -188
  214. {label_studio_sdk-1.0.8.dist-info → label_studio_sdk-1.0.11.dist-info}/WHEEL +1 -1
  215. label_studio_sdk/types/export_convert.py +0 -32
  216. label_studio_sdk/types/export_create.py +0 -54
  217. label_studio_sdk/types/export_create_status.py +0 -5
  218. {label_studio_sdk-1.0.8.dist-info → label_studio_sdk-1.0.11.dist-info}/LICENSE +0 -0
@@ -0,0 +1,200 @@
1
+ import json
2
+ import time
3
+ import asyncio
4
+ import typing
5
+ import pandas as pd
6
+ from .client import ExportsClient, AsyncExportsClient
7
+ from io import BytesIO
8
+ from label_studio_sdk.versions.client import VersionsClient, AsyncVersionsClient
9
+ from label_studio_sdk.core.api_error import ApiError
10
+
11
+
12
+ class ExportTimeoutError(ApiError):
13
+
14
+ def __init__(self, export_snapshot):
15
+ super().__init__(
16
+ status_code=500,
17
+ body=(
18
+ f"Export job timed out after {timeout} seconds: "
19
+ f"unable to retrieve export job {export_snapshot.id}. "
20
+ f"Current status: {export_snapshot.status}. "
21
+ f"Try manually checking the running job with "
22
+ f"`ls.projects.exports.get(project_id={project_id}, export_pk={export_snapshot.id})`."
23
+ )
24
+ )
25
+
26
+ class ExportFailedError(ApiError):
27
+
28
+ def __init__(self, export_snapshot):
29
+ super().__init__(
30
+ status_code=500,
31
+ body=f"Export failed: {export_snapshot}"
32
+ )
33
+
34
+
35
+ def _check_status(export_snapshot, converted_format_id, status):
36
+ if converted_format_id:
37
+ converted_format = next((c for c in export_snapshot.converted_formats if c.id == converted_format_id), None)
38
+ if converted_format and converted_format.status == status:
39
+ return True
40
+ else:
41
+ if export_snapshot.status == status:
42
+ return True
43
+ return False
44
+
45
+
46
+ class ExportsClientExt(ExportsClient):
47
+
48
+ def _bytestream_to_fileobj(self, bytestream: typing.Iterable[bytes] | bytes) -> typing.BinaryIO:
49
+ buffer = BytesIO()
50
+ if isinstance(bytestream, typing.Iterable):
51
+ for chunk in bytestream:
52
+ buffer.write(chunk)
53
+ else:
54
+ buffer.write(bytestream)
55
+ buffer.seek(0)
56
+ return buffer
57
+
58
+ def _bytestream_to_binary(self, bytestream: typing.Iterable[bytes]) -> bytes:
59
+ fileobj = self._bytestream_to_fileobj(bytestream)
60
+ return fileobj.getvalue()
61
+
62
+ def _bytestream_to_json(self, bytestream: typing.Iterable[bytes]) -> dict:
63
+ fileobj = self._bytestream_to_fileobj(bytestream)
64
+ return json.load(fileobj)
65
+
66
+ def _bytestream_to_pandas(self, bytestream: typing.Iterable[bytes]) -> pd.DataFrame:
67
+ fileobj = self._bytestream_to_fileobj(bytestream)
68
+ return pd.read_csv(fileobj)
69
+
70
+ def _poll_export(self, project_id, export_snapshot, converted_format_id, timeout):
71
+ start_time = time.time()
72
+ while not _check_status(export_snapshot, None, 'completed'):
73
+ export_snapshot = self.get(project_id, export_pk=export_snapshot.id)
74
+ if _check_status(export_snapshot, None, 'failed'):
75
+ raise ExportFailedError(export_snapshot)
76
+ if time.time() - start_time > timeout:
77
+ raise ExportTimeoutError(export_snapshot)
78
+ time.sleep(1)
79
+
80
+ def _get_bytestream(
81
+ self,
82
+ project_id: int,
83
+ export_type: str,
84
+ timeout: int = 60,
85
+ create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
86
+ convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
87
+ download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
88
+ ):
89
+ version = VersionsClient(client_wrapper=self._client_wrapper).get()
90
+
91
+ if version.edition == "Enterprise":
92
+ # Enterprise edition exports are async, so we need to wait for the export job to complete
93
+ export_snapshot = self.create(project_id, **(create_kwargs or {}))
94
+ # Poll for base (JSON) export to complete
95
+ self._poll_export(project_id, export_snapshot, None, timeout)
96
+ # Convert to requested format if not JSON
97
+ if export_type != "JSON":
98
+ converted_proc = self.convert(project_id, export_pk=export_snapshot.id, export_type=export_type, **(convert_kwargs or {}))
99
+ self._poll_export(project_id, export_snapshot, converted_proc.converted_format, timeout)
100
+
101
+ bytestream = self.download(project_id, export_pk=export_snapshot.id, export_type=export_type, request_options={'chunk_size': 1024}, **(download_kwargs or {}))
102
+ else:
103
+ # Community edition exports are sync, so we can download the file immediately
104
+ bytestream = self.download_sync(project_id, export_type=export_type, download_all_tasks=True, download_resources=True)
105
+ return bytestream
106
+
107
+ def as_file(self, project_id: int, export_type: str = "JSON", timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
108
+ bytestream = self._get_bytestream(project_id, export_type, timeout, create_kwargs, convert_kwargs, download_kwargs)
109
+ return self._bytestream_to_fileobj(bytestream)
110
+
111
+ def as_binary(self, project_id: int, export_type: str = "JSON", timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
112
+ bytestream = self._get_bytestream(project_id, export_type, timeout, create_kwargs, convert_kwargs, download_kwargs)
113
+ return self._bytestream_to_binary(bytestream)
114
+
115
+ def as_json(self, project_id: int, timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
116
+ bytestream = self._get_bytestream(project_id, "JSON", timeout, create_kwargs, convert_kwargs, download_kwargs)
117
+ return self._bytestream_to_json(bytestream)
118
+
119
+ def as_pandas(self, project_id: int, timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
120
+ bytestream = self._get_bytestream(project_id, "CSV", timeout, create_kwargs, convert_kwargs, download_kwargs)
121
+ return self._bytestream_to_pandas(bytestream)
122
+
123
+ class AsyncExportsClientExt(AsyncExportsClient):
124
+
125
+ async def _bytestream_to_fileobj(self, bytestream: typing.AsyncGenerator[bytes, None] | bytes):
126
+ """Convert bytestream to file-like object"""
127
+ fileobj = BytesIO()
128
+ if isinstance(bytestream, typing.AsyncGenerator):
129
+ async for chunk in bytestream:
130
+ fileobj.write(chunk)
131
+ else:
132
+ fileobj.write(bytestream)
133
+ fileobj.seek(0)
134
+ return fileobj
135
+
136
+ async def _bytestream_to_binary(self, bytestream):
137
+ """Convert bytestream to binary data"""
138
+ fileobj = await self._bytestream_to_fileobj(bytestream)
139
+ return fileobj.getvalue()
140
+
141
+ async def _bytestream_to_json(self, bytestream):
142
+ """Convert bytestream to JSON object"""
143
+ fileobj = await self._bytestream_to_fileobj(bytestream)
144
+ return json.load(fileobj)
145
+
146
+ async def _bytestream_to_pandas(self, bytestream):
147
+ """Convert bytestream to pandas DataFrame"""
148
+ fileobj = await self._bytestream_to_fileobj(bytestream)
149
+ return pd.read_csv(fileobj)
150
+
151
+ async def _poll_export(self, project_id, export_snapshot, converted_format_id, timeout):
152
+ start_time = time.time()
153
+ while not _check_status(export_snapshot, None, 'completed'):
154
+ export_snapshot = await self.get(project_id, export_pk=export_snapshot.id)
155
+ if _check_status(export_snapshot, None, 'failed'):
156
+ raise ExportFailedError(export_snapshot)
157
+ if time.time() - start_time > timeout:
158
+ raise ExportTimeoutError(export_snapshot)
159
+ await asyncio.sleep(1)
160
+
161
+ async def _get_bytestream(
162
+ self,
163
+ project_id: int,
164
+ export_type: str,
165
+ timeout: int = 60,
166
+ create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
167
+ convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
168
+ download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None,
169
+ ):
170
+ version = await AsyncVersionsClient(client_wrapper=self._client_wrapper).get()
171
+ if version.edition == "Enterprise":
172
+ # Enterprise edition exports are async, so we need to wait for the export job to complete
173
+ export_snapshot = await self.create(project_id, **(create_kwargs or {}))
174
+ # Poll for base (JSON) export to complete
175
+ await self._poll_export(project_id, export_snapshot, None, timeout)
176
+ # Convert to requested format if not JSON
177
+ if export_type != "JSON":
178
+ converted_proc = await self.convert(project_id, export_pk=export_snapshot.id, export_type=export_type, **(convert_kwargs or {}))
179
+ await self._poll_export(project_id, export_snapshot, converted_proc.converted_format, timeout)
180
+
181
+ bytestream = self.download(project_id, export_pk=export_snapshot.id, export_type=export_type, request_options={'chunk_size': 1024}, **(download_kwargs or {}))
182
+ else:
183
+ bytestream = self.download_sync(project_id, export_type=export_type, download_all_tasks=True, download_resources=True)
184
+ return bytestream
185
+
186
+ async def as_file(self, project_id: int, export_type: str = "JSON", timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
187
+ bytestream = await self._get_bytestream(project_id, export_type, timeout, create_kwargs, convert_kwargs, download_kwargs)
188
+ return await self._bytestream_to_fileobj(bytestream)
189
+
190
+ async def as_binary(self, project_id: int, export_type: str = "JSON", timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
191
+ bytestream = await self._get_bytestream(project_id, export_type, timeout, create_kwargs, convert_kwargs, download_kwargs)
192
+ return await self._bytestream_to_binary(bytestream)
193
+
194
+ async def as_json(self, project_id: int, timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
195
+ bytestream = await self._get_bytestream(project_id, "JSON", timeout, create_kwargs, convert_kwargs, download_kwargs)
196
+ return await self._bytestream_to_json(bytestream)
197
+
198
+ async def as_pandas(self, project_id: int, timeout: int = 60, create_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, convert_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None, download_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = None):
199
+ bytestream = await self._get_bytestream(project_id, "CSV", timeout, create_kwargs, convert_kwargs, download_kwargs)
200
+ return await self._bytestream_to_pandas(bytestream)
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .exports_convert_response import ExportsConvertResponse
4
+ from .exports_list_formats_response_item import ExportsListFormatsResponseItem
5
+
6
+ __all__ = ["ExportsConvertResponse", "ExportsListFormatsResponseItem"]
@@ -0,0 +1,24 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ....core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from ....types.export_format import ExportFormat
6
+ import pydantic
7
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class ExportsConvertResponse(UniversalBaseModel):
11
+ export_type: typing.Optional[ExportFormat] = None
12
+ converted_format: typing.Optional[int] = pydantic.Field(default=None)
13
+ """
14
+ ID of the converted format
15
+ """
16
+
17
+ if IS_PYDANTIC_V2:
18
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
19
+ else:
20
+
21
+ class Config:
22
+ frozen = True
23
+ smart_union = True
24
+ extra = pydantic.Extra.allow
@@ -0,0 +1,44 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ....core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from ....types.export_format import ExportFormat
6
+ import pydantic
7
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class ExportsListFormatsResponseItem(UniversalBaseModel):
11
+ name: typing.Optional[ExportFormat] = None
12
+ title: typing.Optional[str] = pydantic.Field(default=None)
13
+ """
14
+ Export format title
15
+ """
16
+
17
+ description: typing.Optional[str] = pydantic.Field(default=None)
18
+ """
19
+ Export format description
20
+ """
21
+
22
+ link: typing.Optional[str] = pydantic.Field(default=None)
23
+ """
24
+ Export format documentation link
25
+ """
26
+
27
+ tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
28
+ """
29
+ Export format tags
30
+ """
31
+
32
+ disabled: typing.Optional[bool] = pydantic.Field(default=None)
33
+ """
34
+ If true, the export format is not supported by the project.
35
+ """
36
+
37
+ if IS_PYDANTIC_V2:
38
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
39
+ else:
40
+
41
+ class Config:
42
+ frozen = True
43
+ smart_union = True
44
+ extra = pydantic.Extra.allow
@@ -0,0 +1,2 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+