label-studio-sdk 0.0.32__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. label_studio_sdk/__init__.py +206 -6
  2. label_studio_sdk/_extensions/label_studio_tools/__init__.py +0 -0
  3. label_studio_sdk/_extensions/label_studio_tools/core/__init__.py +0 -0
  4. label_studio_sdk/_extensions/label_studio_tools/core/label_config.py +163 -0
  5. label_studio_sdk/_extensions/label_studio_tools/core/utils/__init__.py +0 -0
  6. label_studio_sdk/_extensions/label_studio_tools/core/utils/exceptions.py +2 -0
  7. label_studio_sdk/_extensions/label_studio_tools/core/utils/io.py +228 -0
  8. label_studio_sdk/_extensions/label_studio_tools/core/utils/params.py +45 -0
  9. label_studio_sdk/_extensions/label_studio_tools/etl/__init__.py +1 -0
  10. label_studio_sdk/_extensions/label_studio_tools/etl/beam.py +34 -0
  11. label_studio_sdk/_extensions/label_studio_tools/etl/example.py +17 -0
  12. label_studio_sdk/_extensions/label_studio_tools/etl/registry.py +67 -0
  13. label_studio_sdk/_extensions/label_studio_tools/postprocessing/__init__.py +0 -0
  14. label_studio_sdk/_extensions/label_studio_tools/postprocessing/video.py +97 -0
  15. label_studio_sdk/_legacy/__init__.py +11 -0
  16. label_studio_sdk/_legacy/client.py +471 -0
  17. label_studio_sdk/_legacy/exceptions.py +10 -0
  18. label_studio_sdk/_legacy/label_interface/__init__.py +1 -0
  19. label_studio_sdk/_legacy/label_interface/base.py +77 -0
  20. label_studio_sdk/_legacy/label_interface/control_tags.py +756 -0
  21. label_studio_sdk/_legacy/label_interface/data_examples.json +96 -0
  22. label_studio_sdk/_legacy/label_interface/interface.py +925 -0
  23. label_studio_sdk/_legacy/label_interface/label_tags.py +72 -0
  24. label_studio_sdk/_legacy/label_interface/object_tags.py +292 -0
  25. label_studio_sdk/_legacy/label_interface/region.py +43 -0
  26. label_studio_sdk/_legacy/objects.py +35 -0
  27. label_studio_sdk/{project.py → _legacy/project.py} +711 -258
  28. label_studio_sdk/_legacy/schema/label_config_schema.json +226 -0
  29. label_studio_sdk/{users.py → _legacy/users.py} +15 -13
  30. label_studio_sdk/{utils.py → _legacy/utils.py} +31 -30
  31. label_studio_sdk/{workspaces.py → _legacy/workspaces.py} +13 -11
  32. label_studio_sdk/actions/__init__.py +2 -0
  33. label_studio_sdk/actions/client.py +150 -0
  34. label_studio_sdk/annotations/__init__.py +2 -0
  35. label_studio_sdk/annotations/client.py +750 -0
  36. label_studio_sdk/client.py +164 -436
  37. label_studio_sdk/converter/__init__.py +7 -0
  38. label_studio_sdk/converter/audio.py +56 -0
  39. label_studio_sdk/converter/brush.py +452 -0
  40. label_studio_sdk/converter/converter.py +1175 -0
  41. label_studio_sdk/converter/exports/__init__.py +0 -0
  42. label_studio_sdk/converter/exports/csv.py +82 -0
  43. label_studio_sdk/converter/exports/csv2.py +103 -0
  44. label_studio_sdk/converter/funsd.py +85 -0
  45. label_studio_sdk/converter/imports/__init__.py +0 -0
  46. label_studio_sdk/converter/imports/coco.py +314 -0
  47. label_studio_sdk/converter/imports/colors.py +198 -0
  48. label_studio_sdk/converter/imports/label_config.py +45 -0
  49. label_studio_sdk/converter/imports/pathtrack.py +269 -0
  50. label_studio_sdk/converter/imports/yolo.py +236 -0
  51. label_studio_sdk/converter/main.py +202 -0
  52. label_studio_sdk/converter/utils.py +473 -0
  53. label_studio_sdk/core/__init__.py +33 -0
  54. label_studio_sdk/core/api_error.py +15 -0
  55. label_studio_sdk/core/client_wrapper.py +55 -0
  56. label_studio_sdk/core/datetime_utils.py +28 -0
  57. label_studio_sdk/core/file.py +38 -0
  58. label_studio_sdk/core/http_client.py +443 -0
  59. label_studio_sdk/core/jsonable_encoder.py +99 -0
  60. label_studio_sdk/core/pagination.py +87 -0
  61. label_studio_sdk/core/pydantic_utilities.py +28 -0
  62. label_studio_sdk/core/query_encoder.py +33 -0
  63. label_studio_sdk/core/remove_none_from_dict.py +11 -0
  64. label_studio_sdk/core/request_options.py +32 -0
  65. label_studio_sdk/data_manager.py +32 -23
  66. label_studio_sdk/environment.py +7 -0
  67. label_studio_sdk/errors/__init__.py +6 -0
  68. label_studio_sdk/errors/bad_request_error.py +8 -0
  69. label_studio_sdk/errors/internal_server_error.py +8 -0
  70. label_studio_sdk/export_storage/__init__.py +28 -0
  71. label_studio_sdk/export_storage/azure/__init__.py +5 -0
  72. label_studio_sdk/export_storage/azure/client.py +722 -0
  73. label_studio_sdk/export_storage/azure/types/__init__.py +6 -0
  74. label_studio_sdk/export_storage/azure/types/azure_create_response.py +52 -0
  75. label_studio_sdk/export_storage/azure/types/azure_update_response.py +52 -0
  76. label_studio_sdk/export_storage/client.py +107 -0
  77. label_studio_sdk/export_storage/gcs/__init__.py +5 -0
  78. label_studio_sdk/export_storage/gcs/client.py +722 -0
  79. label_studio_sdk/export_storage/gcs/types/__init__.py +6 -0
  80. label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +52 -0
  81. label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +52 -0
  82. label_studio_sdk/export_storage/local/__init__.py +5 -0
  83. label_studio_sdk/export_storage/local/client.py +688 -0
  84. label_studio_sdk/export_storage/local/types/__init__.py +6 -0
  85. label_studio_sdk/export_storage/local/types/local_create_response.py +47 -0
  86. label_studio_sdk/export_storage/local/types/local_update_response.py +47 -0
  87. label_studio_sdk/export_storage/redis/__init__.py +5 -0
  88. label_studio_sdk/export_storage/redis/client.py +714 -0
  89. label_studio_sdk/export_storage/redis/types/__init__.py +6 -0
  90. label_studio_sdk/export_storage/redis/types/redis_create_response.py +57 -0
  91. label_studio_sdk/export_storage/redis/types/redis_update_response.py +57 -0
  92. label_studio_sdk/export_storage/s3/__init__.py +5 -0
  93. label_studio_sdk/export_storage/s3/client.py +820 -0
  94. label_studio_sdk/export_storage/s3/types/__init__.py +6 -0
  95. label_studio_sdk/export_storage/s3/types/s3create_response.py +74 -0
  96. label_studio_sdk/export_storage/s3/types/s3update_response.py +74 -0
  97. label_studio_sdk/export_storage/types/__init__.py +5 -0
  98. label_studio_sdk/export_storage/types/export_storage_list_types_response_item.py +30 -0
  99. label_studio_sdk/files/__init__.py +2 -0
  100. label_studio_sdk/files/client.py +556 -0
  101. label_studio_sdk/import_storage/__init__.py +28 -0
  102. label_studio_sdk/import_storage/azure/__init__.py +5 -0
  103. label_studio_sdk/import_storage/azure/client.py +812 -0
  104. label_studio_sdk/import_storage/azure/types/__init__.py +6 -0
  105. label_studio_sdk/import_storage/azure/types/azure_create_response.py +72 -0
  106. label_studio_sdk/import_storage/azure/types/azure_update_response.py +72 -0
  107. label_studio_sdk/import_storage/client.py +107 -0
  108. label_studio_sdk/import_storage/gcs/__init__.py +5 -0
  109. label_studio_sdk/import_storage/gcs/client.py +812 -0
  110. label_studio_sdk/import_storage/gcs/types/__init__.py +6 -0
  111. label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +72 -0
  112. label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +72 -0
  113. label_studio_sdk/import_storage/local/__init__.py +5 -0
  114. label_studio_sdk/import_storage/local/client.py +690 -0
  115. label_studio_sdk/import_storage/local/types/__init__.py +6 -0
  116. label_studio_sdk/import_storage/local/types/local_create_response.py +47 -0
  117. label_studio_sdk/import_storage/local/types/local_update_response.py +47 -0
  118. label_studio_sdk/import_storage/redis/__init__.py +5 -0
  119. label_studio_sdk/import_storage/redis/client.py +768 -0
  120. label_studio_sdk/import_storage/redis/types/__init__.py +6 -0
  121. label_studio_sdk/import_storage/redis/types/redis_create_response.py +62 -0
  122. label_studio_sdk/import_storage/redis/types/redis_update_response.py +62 -0
  123. label_studio_sdk/import_storage/s3/__init__.py +5 -0
  124. label_studio_sdk/import_storage/s3/client.py +912 -0
  125. label_studio_sdk/import_storage/s3/types/__init__.py +6 -0
  126. label_studio_sdk/import_storage/s3/types/s3create_response.py +99 -0
  127. label_studio_sdk/import_storage/s3/types/s3update_response.py +99 -0
  128. label_studio_sdk/import_storage/types/__init__.py +5 -0
  129. label_studio_sdk/import_storage/types/import_storage_list_types_response_item.py +30 -0
  130. label_studio_sdk/ml/__init__.py +19 -0
  131. label_studio_sdk/ml/client.py +981 -0
  132. label_studio_sdk/ml/types/__init__.py +17 -0
  133. label_studio_sdk/ml/types/ml_create_request_auth_method.py +5 -0
  134. label_studio_sdk/ml/types/ml_create_response.py +78 -0
  135. label_studio_sdk/ml/types/ml_create_response_auth_method.py +5 -0
  136. label_studio_sdk/ml/types/ml_update_request_auth_method.py +5 -0
  137. label_studio_sdk/ml/types/ml_update_response.py +78 -0
  138. label_studio_sdk/ml/types/ml_update_response_auth_method.py +5 -0
  139. label_studio_sdk/predictions/__init__.py +2 -0
  140. label_studio_sdk/predictions/client.py +638 -0
  141. label_studio_sdk/projects/__init__.py +6 -0
  142. label_studio_sdk/projects/client.py +1053 -0
  143. label_studio_sdk/projects/exports/__init__.py +2 -0
  144. label_studio_sdk/projects/exports/client.py +930 -0
  145. label_studio_sdk/projects/types/__init__.py +7 -0
  146. label_studio_sdk/projects/types/projects_create_response.py +96 -0
  147. label_studio_sdk/projects/types/projects_import_tasks_response.py +71 -0
  148. label_studio_sdk/projects/types/projects_list_response.py +33 -0
  149. label_studio_sdk/py.typed +0 -0
  150. label_studio_sdk/tasks/__init__.py +5 -0
  151. label_studio_sdk/tasks/client.py +811 -0
  152. label_studio_sdk/tasks/types/__init__.py +6 -0
  153. label_studio_sdk/tasks/types/tasks_list_request_fields.py +5 -0
  154. label_studio_sdk/tasks/types/tasks_list_response.py +48 -0
  155. label_studio_sdk/types/__init__.py +115 -0
  156. label_studio_sdk/types/annotation.py +116 -0
  157. label_studio_sdk/types/annotation_filter_options.py +42 -0
  158. label_studio_sdk/types/annotation_last_action.py +19 -0
  159. label_studio_sdk/types/azure_blob_export_storage.py +112 -0
  160. label_studio_sdk/types/azure_blob_export_storage_status.py +7 -0
  161. label_studio_sdk/types/azure_blob_import_storage.py +113 -0
  162. label_studio_sdk/types/azure_blob_import_storage_status.py +7 -0
  163. label_studio_sdk/types/base_task.py +113 -0
  164. label_studio_sdk/types/base_user.py +42 -0
  165. label_studio_sdk/types/converted_format.py +36 -0
  166. label_studio_sdk/types/converted_format_status.py +5 -0
  167. label_studio_sdk/types/export.py +48 -0
  168. label_studio_sdk/types/export_convert.py +32 -0
  169. label_studio_sdk/types/export_create.py +54 -0
  170. label_studio_sdk/types/export_create_status.py +5 -0
  171. label_studio_sdk/types/export_status.py +5 -0
  172. label_studio_sdk/types/file_upload.py +30 -0
  173. label_studio_sdk/types/filter.py +53 -0
  174. label_studio_sdk/types/filter_group.py +35 -0
  175. label_studio_sdk/types/gcs_export_storage.py +112 -0
  176. label_studio_sdk/types/gcs_export_storage_status.py +7 -0
  177. label_studio_sdk/types/gcs_import_storage.py +113 -0
  178. label_studio_sdk/types/gcs_import_storage_status.py +7 -0
  179. label_studio_sdk/types/local_files_export_storage.py +97 -0
  180. label_studio_sdk/types/local_files_export_storage_status.py +7 -0
  181. label_studio_sdk/types/local_files_import_storage.py +92 -0
  182. label_studio_sdk/types/local_files_import_storage_status.py +7 -0
  183. label_studio_sdk/types/ml_backend.py +89 -0
  184. label_studio_sdk/types/ml_backend_auth_method.py +5 -0
  185. label_studio_sdk/types/ml_backend_state.py +5 -0
  186. label_studio_sdk/types/prediction.py +78 -0
  187. label_studio_sdk/types/project.py +198 -0
  188. label_studio_sdk/types/project_import.py +63 -0
  189. label_studio_sdk/types/project_import_status.py +5 -0
  190. label_studio_sdk/types/project_label_config.py +32 -0
  191. label_studio_sdk/types/project_sampling.py +7 -0
  192. label_studio_sdk/types/project_skip_queue.py +5 -0
  193. label_studio_sdk/types/redis_export_storage.py +117 -0
  194. label_studio_sdk/types/redis_export_storage_status.py +7 -0
  195. label_studio_sdk/types/redis_import_storage.py +112 -0
  196. label_studio_sdk/types/redis_import_storage_status.py +7 -0
  197. label_studio_sdk/types/s3export_storage.py +134 -0
  198. label_studio_sdk/types/s3export_storage_status.py +7 -0
  199. label_studio_sdk/types/s3import_storage.py +140 -0
  200. label_studio_sdk/types/s3import_storage_status.py +7 -0
  201. label_studio_sdk/types/serialization_option.py +36 -0
  202. label_studio_sdk/types/serialization_options.py +45 -0
  203. label_studio_sdk/types/task.py +157 -0
  204. label_studio_sdk/types/task_filter_options.py +49 -0
  205. label_studio_sdk/types/user_simple.py +37 -0
  206. label_studio_sdk/types/view.py +55 -0
  207. label_studio_sdk/types/webhook.py +67 -0
  208. label_studio_sdk/types/webhook_actions_item.py +21 -0
  209. label_studio_sdk/types/webhook_serializer_for_update.py +67 -0
  210. label_studio_sdk/types/webhook_serializer_for_update_actions_item.py +21 -0
  211. label_studio_sdk/users/__init__.py +5 -0
  212. label_studio_sdk/users/client.py +830 -0
  213. label_studio_sdk/users/types/__init__.py +6 -0
  214. label_studio_sdk/users/types/users_get_token_response.py +36 -0
  215. label_studio_sdk/users/types/users_reset_token_response.py +36 -0
  216. label_studio_sdk/version.py +4 -0
  217. label_studio_sdk/views/__init__.py +31 -0
  218. label_studio_sdk/views/client.py +564 -0
  219. label_studio_sdk/views/types/__init__.py +29 -0
  220. label_studio_sdk/views/types/views_create_request_data.py +43 -0
  221. label_studio_sdk/views/types/views_create_request_data_filters.py +43 -0
  222. label_studio_sdk/views/types/views_create_request_data_filters_conjunction.py +5 -0
  223. label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +47 -0
  224. label_studio_sdk/views/types/views_create_request_data_ordering_item.py +38 -0
  225. label_studio_sdk/views/types/views_create_request_data_ordering_item_direction.py +5 -0
  226. label_studio_sdk/views/types/views_update_request_data.py +43 -0
  227. label_studio_sdk/views/types/views_update_request_data_filters.py +43 -0
  228. label_studio_sdk/views/types/views_update_request_data_filters_conjunction.py +5 -0
  229. label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +47 -0
  230. label_studio_sdk/views/types/views_update_request_data_ordering_item.py +38 -0
  231. label_studio_sdk/views/types/views_update_request_data_ordering_item_direction.py +5 -0
  232. label_studio_sdk/webhooks/__init__.py +5 -0
  233. label_studio_sdk/webhooks/client.py +636 -0
  234. label_studio_sdk/webhooks/types/__init__.py +5 -0
  235. label_studio_sdk/webhooks/types/webhooks_update_request_actions_item.py +21 -0
  236. label_studio_sdk-1.0.0.dist-info/METADATA +307 -0
  237. label_studio_sdk-1.0.0.dist-info/RECORD +239 -0
  238. {label_studio_sdk-0.0.32.dist-info → label_studio_sdk-1.0.0.dist-info}/WHEEL +1 -2
  239. docs/__init__.py +0 -3
  240. label_studio_sdk-0.0.32.dist-info/LICENSE +0 -201
  241. label_studio_sdk-0.0.32.dist-info/METADATA +0 -22
  242. label_studio_sdk-0.0.32.dist-info/RECORD +0 -15
  243. label_studio_sdk-0.0.32.dist-info/top_level.txt +0 -3
  244. tests/test_client.py +0 -26
  245. {tests → label_studio_sdk/_extensions}/__init__.py +0 -0
@@ -1,8 +1,208 @@
1
- """ .. include::../docs/index.md
2
- """
3
- from .client import Client
4
- from .project import Project
5
- from .utils import parse_config
1
+ # This file was auto-generated by Fern from our API Definition.
6
2
 
3
+ from .types import (
4
+ Annotation,
5
+ AnnotationFilterOptions,
6
+ AnnotationLastAction,
7
+ AzureBlobExportStorage,
8
+ AzureBlobExportStorageStatus,
9
+ AzureBlobImportStorage,
10
+ AzureBlobImportStorageStatus,
11
+ BaseTask,
12
+ BaseUser,
13
+ ConvertedFormat,
14
+ ConvertedFormatStatus,
15
+ Export,
16
+ ExportConvert,
17
+ ExportCreate,
18
+ ExportCreateStatus,
19
+ ExportStatus,
20
+ FileUpload,
21
+ Filter,
22
+ FilterGroup,
23
+ GcsExportStorage,
24
+ GcsExportStorageStatus,
25
+ GcsImportStorage,
26
+ GcsImportStorageStatus,
27
+ LocalFilesExportStorage,
28
+ LocalFilesExportStorageStatus,
29
+ LocalFilesImportStorage,
30
+ LocalFilesImportStorageStatus,
31
+ MlBackend,
32
+ MlBackendAuthMethod,
33
+ MlBackendState,
34
+ Prediction,
35
+ Project,
36
+ ProjectImport,
37
+ ProjectImportStatus,
38
+ ProjectLabelConfig,
39
+ ProjectSampling,
40
+ ProjectSkipQueue,
41
+ RedisExportStorage,
42
+ RedisExportStorageStatus,
43
+ RedisImportStorage,
44
+ RedisImportStorageStatus,
45
+ S3ExportStorage,
46
+ S3ExportStorageStatus,
47
+ S3ImportStorage,
48
+ S3ImportStorageStatus,
49
+ SerializationOption,
50
+ SerializationOptions,
51
+ Task,
52
+ TaskFilterOptions,
53
+ UserSimple,
54
+ View,
55
+ Webhook,
56
+ WebhookActionsItem,
57
+ WebhookSerializerForUpdate,
58
+ WebhookSerializerForUpdateActionsItem,
59
+ )
60
+ from .errors import BadRequestError, InternalServerError
61
+ from . import (
62
+ actions,
63
+ annotations,
64
+ export_storage,
65
+ files,
66
+ import_storage,
67
+ ml,
68
+ predictions,
69
+ projects,
70
+ tasks,
71
+ users,
72
+ views,
73
+ webhooks,
74
+ )
75
+ from ._legacy import Client
76
+ from .environment import LabelStudioEnvironment
77
+ from .export_storage import ExportStorageListTypesResponseItem
78
+ from .import_storage import ImportStorageListTypesResponseItem
79
+ from .ml import (
80
+ MlCreateRequestAuthMethod,
81
+ MlCreateResponse,
82
+ MlCreateResponseAuthMethod,
83
+ MlUpdateRequestAuthMethod,
84
+ MlUpdateResponse,
85
+ MlUpdateResponseAuthMethod,
86
+ )
87
+ from .projects import ProjectsCreateResponse, ProjectsImportTasksResponse, ProjectsListResponse
88
+ from .tasks import TasksListRequestFields, TasksListResponse
89
+ from .users import UsersGetTokenResponse, UsersResetTokenResponse
90
+ from .version import __version__
91
+ from .views import (
92
+ ViewsCreateRequestData,
93
+ ViewsCreateRequestDataFilters,
94
+ ViewsCreateRequestDataFiltersConjunction,
95
+ ViewsCreateRequestDataFiltersItemsItem,
96
+ ViewsCreateRequestDataOrderingItem,
97
+ ViewsCreateRequestDataOrderingItemDirection,
98
+ ViewsUpdateRequestData,
99
+ ViewsUpdateRequestDataFilters,
100
+ ViewsUpdateRequestDataFiltersConjunction,
101
+ ViewsUpdateRequestDataFiltersItemsItem,
102
+ ViewsUpdateRequestDataOrderingItem,
103
+ ViewsUpdateRequestDataOrderingItemDirection,
104
+ )
105
+ from .webhooks import WebhooksUpdateRequestActionsItem
7
106
 
8
- __version__ = '0.0.32'
107
+ __all__ = [
108
+ "Annotation",
109
+ "AnnotationFilterOptions",
110
+ "AnnotationLastAction",
111
+ "AzureBlobExportStorage",
112
+ "AzureBlobExportStorageStatus",
113
+ "AzureBlobImportStorage",
114
+ "AzureBlobImportStorageStatus",
115
+ "BadRequestError",
116
+ "BaseTask",
117
+ "BaseUser",
118
+ "Client",
119
+ "ConvertedFormat",
120
+ "ConvertedFormatStatus",
121
+ "Export",
122
+ "ExportConvert",
123
+ "ExportCreate",
124
+ "ExportCreateStatus",
125
+ "ExportStatus",
126
+ "ExportStorageListTypesResponseItem",
127
+ "FileUpload",
128
+ "Filter",
129
+ "FilterGroup",
130
+ "GcsExportStorage",
131
+ "GcsExportStorageStatus",
132
+ "GcsImportStorage",
133
+ "GcsImportStorageStatus",
134
+ "ImportStorageListTypesResponseItem",
135
+ "InternalServerError",
136
+ "LabelStudioEnvironment",
137
+ "LocalFilesExportStorage",
138
+ "LocalFilesExportStorageStatus",
139
+ "LocalFilesImportStorage",
140
+ "LocalFilesImportStorageStatus",
141
+ "MlBackend",
142
+ "MlBackendAuthMethod",
143
+ "MlBackendState",
144
+ "MlCreateRequestAuthMethod",
145
+ "MlCreateResponse",
146
+ "MlCreateResponseAuthMethod",
147
+ "MlUpdateRequestAuthMethod",
148
+ "MlUpdateResponse",
149
+ "MlUpdateResponseAuthMethod",
150
+ "Prediction",
151
+ "Project",
152
+ "ProjectImport",
153
+ "ProjectImportStatus",
154
+ "ProjectLabelConfig",
155
+ "ProjectSampling",
156
+ "ProjectSkipQueue",
157
+ "ProjectsCreateResponse",
158
+ "ProjectsImportTasksResponse",
159
+ "ProjectsListResponse",
160
+ "RedisExportStorage",
161
+ "RedisExportStorageStatus",
162
+ "RedisImportStorage",
163
+ "RedisImportStorageStatus",
164
+ "S3ExportStorage",
165
+ "S3ExportStorageStatus",
166
+ "S3ImportStorage",
167
+ "S3ImportStorageStatus",
168
+ "SerializationOption",
169
+ "SerializationOptions",
170
+ "Task",
171
+ "TaskFilterOptions",
172
+ "TasksListRequestFields",
173
+ "TasksListResponse",
174
+ "UserSimple",
175
+ "UsersGetTokenResponse",
176
+ "UsersResetTokenResponse",
177
+ "View",
178
+ "ViewsCreateRequestData",
179
+ "ViewsCreateRequestDataFilters",
180
+ "ViewsCreateRequestDataFiltersConjunction",
181
+ "ViewsCreateRequestDataFiltersItemsItem",
182
+ "ViewsCreateRequestDataOrderingItem",
183
+ "ViewsCreateRequestDataOrderingItemDirection",
184
+ "ViewsUpdateRequestData",
185
+ "ViewsUpdateRequestDataFilters",
186
+ "ViewsUpdateRequestDataFiltersConjunction",
187
+ "ViewsUpdateRequestDataFiltersItemsItem",
188
+ "ViewsUpdateRequestDataOrderingItem",
189
+ "ViewsUpdateRequestDataOrderingItemDirection",
190
+ "Webhook",
191
+ "WebhookActionsItem",
192
+ "WebhookSerializerForUpdate",
193
+ "WebhookSerializerForUpdateActionsItem",
194
+ "WebhooksUpdateRequestActionsItem",
195
+ "__version__",
196
+ "actions",
197
+ "annotations",
198
+ "export_storage",
199
+ "files",
200
+ "import_storage",
201
+ "ml",
202
+ "predictions",
203
+ "projects",
204
+ "tasks",
205
+ "users",
206
+ "views",
207
+ "webhooks",
208
+ ]
@@ -0,0 +1,163 @@
1
+ import logging
2
+ import re
3
+
4
+ from collections import defaultdict
5
+ from lxml import etree
6
+
7
+ from label_studio_sdk._extensions.label_studio_tools.core.utils.exceptions import (
8
+ LabelStudioXMLSyntaxErrorSentryIgnored,
9
+ )
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ _LABEL_TAGS = {"Label", "Choice", "Relation"}
14
+ _NOT_CONTROL_TAGS = {
15
+ "Filter",
16
+ }
17
+ _DIR_APP_NAME = "label-studio"
18
+ _VIDEO_TRACKING_TAGS = {"videorectangle"}
19
+
20
+
21
+ def parse_config(config_string):
22
+ """Parse a given Label Studio labeling configuration and return a structured version of the configuration.
23
+ Useful for formatting results for predicted annotations and determining the type(s) of ML models that might
24
+ be relevant to the labeling project.
25
+
26
+ :param config_string: Label config string
27
+ :return: structured config of the form:
28
+ {
29
+ "<ControlTag>.name": {
30
+ "type": "ControlTag",
31
+ "to_name": ["<ObjectTag1>.name", "<ObjectTag2>.name"],
32
+ "inputs: [
33
+ {"type": "ObjectTag1", "value": "<ObjectTag1>.value"},
34
+ {"type": "ObjectTag2", "value": "<ObjectTag2>.value"}
35
+ ],
36
+ "labels": ["Label1", "Label2", "Label3"] // taken from "alias" if it exists, else "value"
37
+ }
38
+ """
39
+ if not config_string:
40
+ return {}
41
+
42
+ try:
43
+ xml_tree = etree.fromstring(config_string)
44
+ except etree.XMLSyntaxError as e:
45
+ raise LabelStudioXMLSyntaxErrorSentryIgnored(str(e))
46
+ inputs, outputs, labels = {}, {}, defaultdict(dict)
47
+ # Add variables to config (e.g. {{idx}} for index in Repeater
48
+ variables = []
49
+ for tag in xml_tree.iter():
50
+ if tag.attrib and "indexFlag" in tag.attrib:
51
+ variables.append(tag.attrib["indexFlag"])
52
+ if _is_output_tag(tag):
53
+ tag_info = {"type": tag.tag, "to_name": tag.attrib["toName"].split(",")}
54
+ if variables:
55
+ # Find variables in tag_name and regex if find it
56
+ for v in variables:
57
+ for tag_name in tag_info["to_name"]:
58
+ if v in tag_name:
59
+ if "regex" not in tag_info:
60
+ tag_info["regex"] = {}
61
+ tag_info["regex"][v] = ".*"
62
+ # Grab conditionals if any
63
+ conditionals = {}
64
+ if tag.attrib.get("perRegion") == "true":
65
+ if tag.attrib.get("whenTagName"):
66
+ conditionals = {"type": "tag", "name": tag.attrib["whenTagName"]}
67
+ elif tag.attrib.get("whenLabelValue"):
68
+ conditionals = {
69
+ "type": "label",
70
+ "name": tag.attrib["whenLabelValue"],
71
+ }
72
+ elif tag.attrib.get("whenChoiceValue"):
73
+ conditionals = {
74
+ "type": "choice",
75
+ "name": tag.attrib["whenChoiceValue"],
76
+ }
77
+ if conditionals:
78
+ tag_info["conditionals"] = conditionals
79
+ if has_variable(tag.attrib.get("value", "")) or tag.attrib.get("apiUrl"):
80
+ tag_info["dynamic_labels"] = True
81
+ outputs[tag.attrib["name"]] = tag_info
82
+ elif _is_input_tag(tag):
83
+ inputs[tag.attrib["name"]] = {
84
+ "type": tag.tag,
85
+ "value": tag.attrib["value"].lstrip("$"),
86
+ "valueType": tag.attrib.get("valueType"),
87
+ }
88
+ if tag.tag not in _LABEL_TAGS:
89
+ continue
90
+ parent_name = _get_parent_output_tag_name(tag, outputs)
91
+ if parent_name is not None:
92
+ actual_value = tag.attrib.get("alias") or tag.attrib.get("value")
93
+ if not actual_value:
94
+ logger.debug(
95
+ 'Inspecting tag {tag_name}... found no "value" or "alias" attributes.'.format(
96
+ tag_name=etree.tostring(tag, encoding="unicode").strip()[:50]
97
+ )
98
+ )
99
+ else:
100
+ labels[parent_name][actual_value] = dict(tag.attrib)
101
+ for output_tag, tag_info in outputs.items():
102
+ tag_info["inputs"] = []
103
+ for input_tag_name in tag_info["to_name"]:
104
+ if input_tag_name not in inputs:
105
+ logger.info(
106
+ f"to_name={input_tag_name} is specified for output tag name={output_tag}, "
107
+ "but we can't find it among input tags"
108
+ )
109
+ continue
110
+ tag_info["inputs"].append(inputs[input_tag_name])
111
+ tag_info["labels"] = list(labels[output_tag])
112
+ tag_info["labels_attrs"] = labels[output_tag]
113
+ return outputs
114
+
115
+
116
+ def is_video_object_tracking(parsed_config):
117
+ for component in parsed_config:
118
+ if parsed_config[component]["type"].lower() in _VIDEO_TRACKING_TAGS:
119
+ return True
120
+
121
+
122
+ def has_variable(actual_value):
123
+ """
124
+ Check if value has variable
125
+ :param actual_value: value to check
126
+ :return: True if value has variable
127
+ """
128
+ expression = "^\$[A-Za-z_]+$"
129
+ pattern = re.compile(expression)
130
+ full_match = pattern.fullmatch(actual_value)
131
+ if full_match:
132
+ return True
133
+ return False
134
+
135
+
136
+ def _is_input_tag(tag):
137
+ """
138
+ Check if tag is input
139
+ """
140
+ return tag.attrib.get("name") and tag.attrib.get("value")
141
+
142
+
143
+ def _is_output_tag(tag):
144
+ """
145
+ Check if tag is output
146
+ """
147
+ return (
148
+ tag.attrib.get("name")
149
+ and tag.attrib.get("toName")
150
+ and tag.tag not in _NOT_CONTROL_TAGS
151
+ )
152
+
153
+
154
+ def _get_parent_output_tag_name(tag, outputs):
155
+ # Find parental <Choices> tag for nested tags like <Choices><View><View><Choice>...
156
+ parent = tag
157
+ while True:
158
+ parent = parent.getparent()
159
+ if parent is None:
160
+ return
161
+ name = parent.attrib.get("name")
162
+ if name in outputs:
163
+ return name
@@ -0,0 +1,2 @@
1
+ class LabelStudioXMLSyntaxErrorSentryIgnored(Exception):
2
+ pass
@@ -0,0 +1,228 @@
1
+ import logging
2
+ import io
3
+ import shutil
4
+ import urllib
5
+ import hashlib
6
+ import requests
7
+ import os
8
+
9
+ from appdirs import user_cache_dir, user_data_dir
10
+ from urllib.parse import urlparse, urljoin
11
+ from contextlib import contextmanager
12
+ from tempfile import mkdtemp
13
+
14
+ from label_studio_sdk._extensions.label_studio_tools.core.utils.params import get_env
15
+
16
+ _DIR_APP_NAME = "label-studio"
17
+ LOCAL_FILES_DOCUMENT_ROOT = get_env(
18
+ "LOCAL_FILES_DOCUMENT_ROOT", default=os.path.abspath(os.sep)
19
+ )
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ def concat_urls(base_url, url):
25
+ return base_url.rstrip("/") + "/" + url.lstrip("/")
26
+
27
+
28
+ def get_data_dir():
29
+ data_dir = user_data_dir(appname=_DIR_APP_NAME)
30
+ os.makedirs(data_dir, exist_ok=True)
31
+ return data_dir
32
+
33
+
34
+ def get_cache_dir():
35
+ cache_dir = user_cache_dir(appname=_DIR_APP_NAME)
36
+ os.makedirs(cache_dir, exist_ok=True)
37
+ return cache_dir
38
+
39
+
40
+ def get_local_path(
41
+ url,
42
+ cache_dir=None,
43
+ project_dir=None,
44
+ hostname=None,
45
+ image_dir=None,
46
+ access_token=None,
47
+ download_resources=True,
48
+ task_id=None,
49
+ ):
50
+ f"""This helper function is used to download (cache) url and return local path to it.
51
+
52
+ :param url: File URL to download, it can be a uploaded file, local storage, cloud storage file or just http(s) url
53
+ :param cache_dir: Cache directory to download or copy files
54
+ :param project_dir: Project directory
55
+ :param hostname: Label Studio Hostname, it will be used for uploaded files, local storage files and cloud storage files
56
+ if not provided, it will be taken from LABEL_STUDIO_URL env variable
57
+ :param image_dir: Image and other media upload directory
58
+ :param access_token: Label Studio access token, it will be used for uploaded files, local storage files and cloud storage files
59
+ if not provided, it will be taken from LABEL_STUDIO_API_KEY env variable
60
+ :param download_resources: Download and cache a file from URL
61
+ :param task_id: Label Studio Task ID, required for cloud storage files
62
+ because the URL will be rebuilt to `{hostname}/tasks/{task_id}/presign/?fileuri={url}`
63
+
64
+ :return: filepath
65
+ """
66
+ # get environment variables
67
+ hostname = (
68
+ hostname
69
+ or os.getenv("LABEL_STUDIO_URL", "")
70
+ or os.getenv("LABEL_STUDIO_HOST", "")
71
+ )
72
+ access_token = (
73
+ access_token
74
+ or os.getenv("LABEL_STUDIO_API_KEY", "")
75
+ or os.getenv("LABEL_STUDIO_ACCESS_TOKEN", "")
76
+ )
77
+ if "localhost" in hostname:
78
+ logger.warning(
79
+ f"Using `localhost` ({hostname}) in LABEL_STUDIO_URL, "
80
+ f"`localhost` is not accessible inside of docker containers. "
81
+ f"You can check your IP with utilities like `ifconfig` and set it as LABEL_STUDIO_URL."
82
+ )
83
+
84
+ # fix file upload url
85
+ if url.startswith("upload") or url.startswith("/upload"):
86
+ url = "/data" + ("" if url.startswith("/") else "/") + url
87
+
88
+ is_uploaded_file = url.startswith("/data/upload")
89
+ is_local_storage_file = url.startswith("/data/") and "?d=" in url
90
+ is_cloud_storage_file = (
91
+ url.startswith("s3:") or url.startswith("gs:") or url.startswith("azure-blob:")
92
+ )
93
+
94
+ # Local storage file: try to load locally otherwise download below
95
+ # this code allow to read Local Storage files directly from a directory
96
+ # instead of downloading them from LS instance
97
+ if is_local_storage_file:
98
+ filepath = url.split("?d=")[1]
99
+ filepath = os.path.join(LOCAL_FILES_DOCUMENT_ROOT, filepath)
100
+ if os.path.exists(filepath):
101
+ logger.debug(
102
+ f"Local Storage file path exists locally, use it as a local file: {filepath}"
103
+ )
104
+ return filepath
105
+
106
+ # try to get local directories
107
+ if image_dir is None:
108
+ upload_dir = os.path.join(get_data_dir(), "media", "upload")
109
+ image_dir = project_dir and os.path.join(project_dir, "upload") or upload_dir
110
+ logger.debug(
111
+ f"Image and upload dirs: image_dir={image_dir}, upload_dir={upload_dir}"
112
+ )
113
+
114
+ # Uploaded file: try to load locally otherwise download below
115
+ # this code allow to read Uploaded files directly from a directory
116
+ # instead of downloading them from LS instance
117
+ if is_uploaded_file and os.path.exists(image_dir):
118
+ project_id = url.split("/")[-2] # To retrieve project_id
119
+ filepath = os.path.join(image_dir, project_id, os.path.basename(url))
120
+ if cache_dir and download_resources:
121
+ shutil.copy(filepath, cache_dir)
122
+ if os.path.exists(filepath):
123
+ logger.debug(f"Uploaded file: Path exists in image_dir: {filepath}")
124
+ return filepath
125
+
126
+ # Upload or Local Storage file
127
+ if is_uploaded_file or is_local_storage_file or is_cloud_storage_file:
128
+ # hostname check
129
+ if not hostname:
130
+ raise FileNotFoundError(
131
+ f"Can't resolve url, neither hostname or project_dir passed: {url}. "
132
+ "You can set LABEL_STUDIO_URL environment variable to use it as a hostname."
133
+ )
134
+ # uploaded and local storage file
135
+ elif is_uploaded_file or is_local_storage_file:
136
+ url = concat_urls(hostname, url)
137
+ logger.info("Resolving url using hostname [" + hostname + "]: " + url)
138
+ # s3, gs, azure-blob file
139
+ elif is_cloud_storage_file:
140
+ if task_id is None:
141
+ raise Exception(
142
+ "Label Studio Task ID is required for cloud storage files"
143
+ )
144
+ url = concat_urls(hostname, f"/tasks/{task_id}/presign/?fileuri={url}")
145
+ logger.info(
146
+ "Cloud storage file: Resolving url using hostname ["
147
+ + hostname
148
+ + "]: "
149
+ + url
150
+ )
151
+
152
+ # check access token
153
+ if not access_token:
154
+ raise FileNotFoundError(
155
+ "To access uploaded and local storage files you have to "
156
+ "set LABEL_STUDIO_API_KEY environment variable."
157
+ )
158
+
159
+ filepath = download_and_cache(
160
+ url,
161
+ cache_dir,
162
+ download_resources,
163
+ hostname,
164
+ access_token,
165
+ is_local_storage_file,
166
+ is_cloud_storage_file,
167
+ )
168
+ return filepath
169
+
170
+
171
+ def download_and_cache(
172
+ url,
173
+ cache_dir,
174
+ download_resources,
175
+ hostname,
176
+ access_token,
177
+ is_local_storage_file,
178
+ is_cloud_storage_file,
179
+ ):
180
+ # File specified by remote URL - download and cache it
181
+ cache_dir = cache_dir or get_cache_dir()
182
+ parsed_url = urlparse(url)
183
+ url_filename = (
184
+ # /data/local-files?d=dir/1.jpg => 1.jpg
185
+ os.path.basename(url)
186
+ if is_local_storage_file or is_cloud_storage_file
187
+ # /some/url/1.jpg?expire=xxx => 1.jpg
188
+ else os.path.basename(parsed_url.path)
189
+ )
190
+ url_hash = hashlib.md5(url.encode()).hexdigest()[:8]
191
+ filepath = os.path.join(cache_dir, url_hash + "__" + url_filename)
192
+
193
+ if not os.path.exists(filepath):
194
+ logger.info("Download {url} to {filepath}".format(url=url, filepath=filepath))
195
+ if download_resources:
196
+ headers = {
197
+ # avoid requests.exceptions.HTTPError: 403 Client Error: Forbidden. Please comply with the User-Agent policy:
198
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"
199
+ }
200
+ # check if url matches hostname - then uses access token to this Label Studio instance
201
+ if (
202
+ access_token
203
+ and hostname
204
+ and parsed_url.netloc == urlparse(hostname).netloc
205
+ ):
206
+ headers["Authorization"] = "Token " + access_token
207
+ logger.debug("Authorization token is used for download_and_cache")
208
+ r = requests.get(url, stream=True, headers=headers)
209
+ r.raise_for_status()
210
+ with io.open(filepath, mode="wb") as fout:
211
+ fout.write(r.content)
212
+ return filepath
213
+
214
+
215
+ @contextmanager
216
+ def get_temp_dir():
217
+ dirpath = mkdtemp()
218
+ yield dirpath
219
+ shutil.rmtree(dirpath)
220
+
221
+
222
+ def get_all_files_from_dir(d):
223
+ out = []
224
+ for name in os.listdir(d):
225
+ filepath = os.path.join(d, name)
226
+ if os.path.isfile(filepath):
227
+ out.append(filepath)
228
+ return out
@@ -0,0 +1,45 @@
1
+ import os
2
+
3
+
4
+ def bool_from_request(params, key, default):
5
+ """Get boolean value from request GET, POST, etc
6
+ :param params: dict POST, GET, etc
7
+ :param key: key to find
8
+ :param default: default value
9
+ :return: boolean
10
+ """
11
+ value = params.get(key, default)
12
+
13
+ if isinstance(value, str):
14
+ value = cast_bool_from_str(value)
15
+
16
+ return bool(int(value))
17
+
18
+
19
+ def cast_bool_from_str(value):
20
+ if isinstance(value, str):
21
+ if value.lower() in ["true", "yes", "on", "1"]:
22
+ value = True
23
+ elif value.lower() in ["false", "no", "not", "off", "0"]:
24
+ value = False
25
+ else:
26
+ raise ValueError(
27
+ f'Incorrect bool value "{value}". '
28
+ f"It should be one of [1, 0, true, false, yes, no]"
29
+ )
30
+ return value
31
+
32
+
33
+ def get_env(name, default=None, is_bool=False):
34
+ for env_key in ["LABEL_STUDIO_" + name, "HEARTEX_" + name, name]:
35
+ value = os.environ.get(env_key)
36
+ if value is not None:
37
+ if is_bool:
38
+ return bool_from_request(os.environ, env_key, default)
39
+ else:
40
+ return value
41
+ return default
42
+
43
+
44
+ def get_bool_env(key, default):
45
+ return get_env(key, default, is_bool=True)
@@ -0,0 +1 @@
1
+ from registry import transform
@@ -0,0 +1,34 @@
1
+ import apache_beam as beam
2
+ from registry import dataloader, call_dataloader
3
+
4
+
5
+ class CallDataLoader(beam.DoFn):
6
+ def __init__(self, dataloader_name):
7
+ self.dataloader_name = dataloader_name
8
+
9
+ def setup(self):
10
+ print("Setup!")
11
+ pass
12
+
13
+ def process(self, element, *args, **kwargs):
14
+ return call_dataloader(self.dataloader_name, element, *args, **kwargs)
15
+
16
+ def teardown(self):
17
+ print("Teardown!")
18
+ pass
19
+
20
+
21
+ @dataloader("test")
22
+ def f(i, k):
23
+ print("I!!", k)
24
+ yield i
25
+
26
+
27
+ with beam.Pipeline() as pipeline:
28
+ results = (
29
+ pipeline
30
+ | "Get storage keys" >> beam.io.gcp.gcsio.list_files("bucket")
31
+ | "Run dataloader"
32
+ >> beam.FlatMap(fn=CallDataLoader("test"), **dataloader_kwargs)
33
+ | "Load into Vector DB" >> beam.ParDo(fn=LoadDataRecordInDB)
34
+ )