label-studio-sdk 2.0.5__py3-none-any.whl → 2.0.7__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 (92) hide show
  1. label_studio_sdk/__init__.py +70 -0
  2. label_studio_sdk/annotation_history/__init__.py +5 -0
  3. label_studio_sdk/annotation_history/client.py +415 -0
  4. label_studio_sdk/annotation_history/types/__init__.py +5 -0
  5. label_studio_sdk/annotation_history/types/annotation_history_delete_response.py +22 -0
  6. label_studio_sdk/annotation_reviews/__init__.py +2 -0
  7. label_studio_sdk/annotation_reviews/client.py +713 -0
  8. label_studio_sdk/base_client.py +20 -0
  9. label_studio_sdk/blueprints/__init__.py +2 -0
  10. label_studio_sdk/blueprints/client.py +272 -0
  11. label_studio_sdk/core/client_wrapper.py +2 -1
  12. label_studio_sdk/export_storage/__init__.py +2 -2
  13. label_studio_sdk/export_storage/azure_spi/__init__.py +2 -0
  14. label_studio_sdk/export_storage/azure_spi/client.py +1354 -0
  15. label_studio_sdk/export_storage/client.py +8 -0
  16. label_studio_sdk/export_storage/gcswif/__init__.py +2 -0
  17. label_studio_sdk/export_storage/gcswif/client.py +1376 -0
  18. label_studio_sdk/import_storage/__init__.py +2 -2
  19. label_studio_sdk/import_storage/azure_spi/__init__.py +2 -0
  20. label_studio_sdk/import_storage/azure_spi/client.py +1378 -0
  21. label_studio_sdk/import_storage/client.py +8 -0
  22. label_studio_sdk/import_storage/gcswif/__init__.py +2 -0
  23. label_studio_sdk/import_storage/gcswif/client.py +1400 -0
  24. label_studio_sdk/jwt_settings/client.py +10 -8
  25. label_studio_sdk/label_interface/control_tags.py +38 -0
  26. label_studio_sdk/label_interface/data_examples.json +10 -0
  27. label_studio_sdk/label_interface/interface.py +13 -0
  28. label_studio_sdk/label_interface/object_tags.py +9 -0
  29. label_studio_sdk/ml/client.py +124 -0
  30. label_studio_sdk/organizations/__init__.py +3 -2
  31. label_studio_sdk/organizations/client.py +536 -1
  32. label_studio_sdk/organizations/invites/__init__.py +2 -0
  33. label_studio_sdk/organizations/invites/client.py +368 -0
  34. label_studio_sdk/organizations/types/__init__.py +5 -0
  35. label_studio_sdk/organizations/types/patched_default_role_request_custom_scripts_editable_by.py +7 -0
  36. label_studio_sdk/project_templates/__init__.py +2 -0
  37. label_studio_sdk/project_templates/client.py +909 -0
  38. label_studio_sdk/projects/client.py +8 -0
  39. label_studio_sdk/projects/members/__init__.py +2 -2
  40. label_studio_sdk/projects/members/bulk/client.py +46 -2
  41. label_studio_sdk/projects/members/client.py +4 -0
  42. label_studio_sdk/projects/members/paginated/__init__.py +2 -0
  43. label_studio_sdk/projects/members/paginated/client.py +248 -0
  44. label_studio_sdk/session_policy/__init__.py +2 -0
  45. label_studio_sdk/session_policy/client.py +247 -0
  46. label_studio_sdk/tasks/client.py +371 -0
  47. label_studio_sdk/types/__init__.py +56 -0
  48. label_studio_sdk/types/action_enum.py +19 -0
  49. label_studio_sdk/types/all_roles_project_list.py +1 -1
  50. label_studio_sdk/types/annotation.py +7 -0
  51. label_studio_sdk/types/annotation_history.py +81 -0
  52. label_studio_sdk/types/annotation_history_action.py +7 -0
  53. label_studio_sdk/types/annotation_request.py +7 -0
  54. label_studio_sdk/types/annotation_review.py +61 -0
  55. label_studio_sdk/types/annotation_review_request.py +41 -0
  56. label_studio_sdk/types/azure_service_principal_export_storage.py +114 -0
  57. label_studio_sdk/types/azure_service_principal_export_storage_request.py +107 -0
  58. label_studio_sdk/types/azure_service_principal_import_storage.py +115 -0
  59. label_studio_sdk/types/azure_service_principal_import_storage_request.py +108 -0
  60. label_studio_sdk/types/blueprint.py +41 -0
  61. label_studio_sdk/types/default_role.py +75 -0
  62. label_studio_sdk/types/default_role_custom_scripts_editable_by.py +7 -0
  63. label_studio_sdk/types/gcswif_export_storage.py +119 -0
  64. label_studio_sdk/types/gcswif_export_storage_request.py +112 -0
  65. label_studio_sdk/types/gcswif_import_storage.py +120 -0
  66. label_studio_sdk/types/gcswif_import_storage_request.py +113 -0
  67. label_studio_sdk/types/lse_project.py +223 -0
  68. label_studio_sdk/types/lse_project_sampling.py +7 -0
  69. label_studio_sdk/types/lse_project_skip_queue.py +7 -0
  70. label_studio_sdk/types/lse_project_update.py +1 -0
  71. label_studio_sdk/types/lse_task.py +1 -0
  72. label_studio_sdk/types/lse_task_serializer_for_reviewers.py +1 -0
  73. label_studio_sdk/types/lsejwt_settings.py +1 -5
  74. label_studio_sdk/types/paginated_annotation_history_list.py +23 -0
  75. label_studio_sdk/types/paginated_lse_user_list.py +23 -0
  76. label_studio_sdk/types/paginated_paginated_project_member_list.py +23 -0
  77. label_studio_sdk/types/paginated_project_member.py +50 -0
  78. label_studio_sdk/types/project_member_bulk_assign_roles_request.py +21 -0
  79. label_studio_sdk/types/project_template.py +41 -0
  80. label_studio_sdk/types/project_template_request.py +38 -0
  81. label_studio_sdk/types/review_settings.py +5 -0
  82. label_studio_sdk/types/review_settings_request.py +5 -0
  83. label_studio_sdk/types/session_timeout_policy.py +31 -0
  84. label_studio_sdk/types/task_event.py +61 -0
  85. label_studio_sdk/workspaces/members/__init__.py +2 -2
  86. label_studio_sdk/workspaces/members/client.py +4 -0
  87. label_studio_sdk/workspaces/members/paginated/__init__.py +2 -0
  88. label_studio_sdk/workspaces/members/paginated/client.py +212 -0
  89. {label_studio_sdk-2.0.5.dist-info → label_studio_sdk-2.0.7.dist-info}/METADATA +2 -2
  90. {label_studio_sdk-2.0.5.dist-info → label_studio_sdk-2.0.7.dist-info}/RECORD +92 -36
  91. {label_studio_sdk-2.0.5.dist-info → label_studio_sdk-2.0.7.dist-info}/LICENSE +0 -0
  92. {label_studio_sdk-2.0.5.dist-info → label_studio_sdk-2.0.7.dist-info}/WHEEL +0 -0
@@ -0,0 +1,41 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ import datetime as dt
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class ProjectTemplate(UncheckedBaseModel):
11
+ assignment_settings: typing.Optional[typing.Optional[typing.Any]] = None
12
+ created_at: dt.datetime
13
+ created_by: typing.Optional[int] = None
14
+ custom_script: typing.Optional[str] = pydantic.Field(default=None)
15
+ """
16
+ custom script for projects created from this template
17
+ """
18
+
19
+ description: typing.Optional[str] = None
20
+ id: int
21
+ name: str
22
+ organization: typing.Optional[int] = None
23
+ project_settings: typing.Optional[typing.Optional[typing.Any]] = None
24
+ require_comment_on_skip: typing.Optional[bool] = pydantic.Field(default=None)
25
+ """
26
+ flag to require comment on skip
27
+ """
28
+
29
+ review_settings: typing.Optional[typing.Optional[typing.Any]] = None
30
+ show_unused_data_columns_to_annotators: typing.Optional[bool] = None
31
+ tags: typing.Optional[typing.Optional[typing.Any]] = None
32
+ updated_at: dt.datetime
33
+
34
+ if IS_PYDANTIC_V2:
35
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
36
+ else:
37
+
38
+ class Config:
39
+ frozen = True
40
+ smart_union = True
41
+ extra = pydantic.Extra.allow
@@ -0,0 +1,38 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+
8
+
9
+ class ProjectTemplateRequest(UncheckedBaseModel):
10
+ assignment_settings: typing.Optional[typing.Optional[typing.Any]] = None
11
+ created_by: typing.Optional[int] = None
12
+ custom_script: typing.Optional[str] = pydantic.Field(default=None)
13
+ """
14
+ custom script for projects created from this template
15
+ """
16
+
17
+ description: typing.Optional[str] = None
18
+ name: str
19
+ organization: typing.Optional[int] = None
20
+ project_id: int
21
+ project_settings: typing.Optional[typing.Optional[typing.Any]] = None
22
+ require_comment_on_skip: typing.Optional[bool] = pydantic.Field(default=None)
23
+ """
24
+ flag to require comment on skip
25
+ """
26
+
27
+ review_settings: typing.Optional[typing.Optional[typing.Any]] = None
28
+ show_unused_data_columns_to_annotators: typing.Optional[bool] = None
29
+ tags: typing.Optional[typing.Optional[typing.Any]] = None
30
+
31
+ if IS_PYDANTIC_V2:
32
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
33
+ else:
34
+
35
+ class Config:
36
+ frozen = True
37
+ smart_union = True
38
+ extra = pydantic.Extra.allow
@@ -69,6 +69,11 @@ class ReviewSettings(UncheckedBaseModel):
69
69
  Show instructions to the reviewers before they start
70
70
  """
71
71
 
72
+ show_unused_data_columns_to_reviewers: typing.Optional[bool] = pydantic.Field(default=None)
73
+ """
74
+ If true, Data Manager shows all task.data columns to reviewers; if false, hides columns not referenced by the label interface
75
+ """
76
+
72
77
  if IS_PYDANTIC_V2:
73
78
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
74
79
  else:
@@ -69,6 +69,11 @@ class ReviewSettingsRequest(UncheckedBaseModel):
69
69
  Show instructions to the reviewers before they start
70
70
  """
71
71
 
72
+ show_unused_data_columns_to_reviewers: typing.Optional[bool] = pydantic.Field(default=None)
73
+ """
74
+ If true, Data Manager shows all task.data columns to reviewers; if false, hides columns not referenced by the label interface
75
+ """
76
+
72
77
  if IS_PYDANTIC_V2:
73
78
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
74
79
  else:
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import datetime as dt
5
+ import typing
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class SessionTimeoutPolicy(UncheckedBaseModel):
11
+ created_at: dt.datetime
12
+ max_session_age: typing.Optional[int] = pydantic.Field(default=None)
13
+ """
14
+ Number of minutes that a session can be active before needing to re-login
15
+ """
16
+
17
+ max_time_between_activity: typing.Optional[int] = pydantic.Field(default=None)
18
+ """
19
+ Number of minutes that a session stays active without any activity
20
+ """
21
+
22
+ updated_at: dt.datetime
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,61 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ import pydantic
6
+ import datetime as dt
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class TaskEvent(UncheckedBaseModel):
11
+ """
12
+ Serializer for TaskEvent model to handle event creation from frontend.
13
+
14
+ This serializer validates and processes task events sent from the labeling interface,
15
+ ensuring proper data format and automatically setting required relationships.
16
+ """
17
+
18
+ actor: int
19
+ annotation: typing.Optional[int] = pydantic.Field(default=None)
20
+ """
21
+ Annotation ID associated with this event
22
+ """
23
+
24
+ annotation_draft: typing.Optional[int] = pydantic.Field(default=None)
25
+ """
26
+ Draft annotation ID associated with this event
27
+ """
28
+
29
+ created_at: dt.datetime
30
+ event_key: str = pydantic.Field()
31
+ """
32
+ Event type identifier (e.g., "annotation_loaded", "region_finished_drawing")
33
+ """
34
+
35
+ event_time: dt.datetime = pydantic.Field()
36
+ """
37
+ Timestamp when the event occurred (frontend time)
38
+ """
39
+
40
+ id: int
41
+ meta: typing.Optional[typing.Optional[typing.Any]] = None
42
+ organization: int
43
+ project: int
44
+ review: typing.Optional[int] = pydantic.Field(default=None)
45
+ """
46
+ Review ID associated with this event
47
+ """
48
+
49
+ task: int = pydantic.Field()
50
+ """
51
+ Task this event is associated with
52
+ """
53
+
54
+ if IS_PYDANTIC_V2:
55
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
56
+ else:
57
+
58
+ class Config:
59
+ frozen = True
60
+ smart_union = True
61
+ extra = pydantic.Extra.allow
@@ -1,6 +1,6 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- from . import bulk
3
+ from . import bulk, paginated
4
4
  from .bulk import BulkDeleteResponse, BulkPostResponse
5
5
 
6
- __all__ = ["BulkDeleteResponse", "BulkPostResponse", "bulk"]
6
+ __all__ = ["BulkDeleteResponse", "BulkPostResponse", "bulk", "paginated"]
@@ -3,6 +3,7 @@
3
3
  import typing
4
4
  from ...core.client_wrapper import SyncClientWrapper
5
5
  from .bulk.client import BulkClient
6
+ from .paginated.client import PaginatedClient
6
7
  from ...core.request_options import RequestOptions
7
8
  from ...types.workspace_member_list import WorkspaceMemberList
8
9
  from ...core.jsonable_encoder import jsonable_encoder
@@ -12,6 +13,7 @@ from ...core.api_error import ApiError
12
13
  from ...types.workspace_member_create import WorkspaceMemberCreate
13
14
  from ...core.client_wrapper import AsyncClientWrapper
14
15
  from .bulk.client import AsyncBulkClient
16
+ from .paginated.client import AsyncPaginatedClient
15
17
 
16
18
  # this is used as the default value for optional parameters
17
19
  OMIT = typing.cast(typing.Any, ...)
@@ -21,6 +23,7 @@ class MembersClient:
21
23
  def __init__(self, *, client_wrapper: SyncClientWrapper):
22
24
  self._client_wrapper = client_wrapper
23
25
  self.bulk = BulkClient(client_wrapper=self._client_wrapper)
26
+ self.paginated = PaginatedClient(client_wrapper=self._client_wrapper)
24
27
 
25
28
  def list(
26
29
  self, id: int, *, request_options: typing.Optional[RequestOptions] = None
@@ -182,6 +185,7 @@ class AsyncMembersClient:
182
185
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
183
186
  self._client_wrapper = client_wrapper
184
187
  self.bulk = AsyncBulkClient(client_wrapper=self._client_wrapper)
188
+ self.paginated = AsyncPaginatedClient(client_wrapper=self._client_wrapper)
185
189
 
186
190
  async def list(
187
191
  self, id: int, *, request_options: typing.Optional[RequestOptions] = None
@@ -0,0 +1,2 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
@@ -0,0 +1,212 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ....core.client_wrapper import SyncClientWrapper
4
+ import typing
5
+ from ....core.request_options import RequestOptions
6
+ from ....core.pagination import SyncPager
7
+ from ....types.lse_user import LseUser
8
+ from ....core.jsonable_encoder import jsonable_encoder
9
+ from ....types.paginated_lse_user_list import PaginatedLseUserList
10
+ from ....core.unchecked_base_model import construct_type
11
+ from json.decoder import JSONDecodeError
12
+ from ....core.api_error import ApiError
13
+ from ....core.client_wrapper import AsyncClientWrapper
14
+ from ....core.pagination import AsyncPager
15
+
16
+
17
+ class PaginatedClient:
18
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
19
+ self._client_wrapper = client_wrapper
20
+
21
+ def list(
22
+ self,
23
+ id: int,
24
+ *,
25
+ ids: typing.Optional[str] = None,
26
+ page: typing.Optional[int] = None,
27
+ page_size: typing.Optional[int] = None,
28
+ search: typing.Optional[str] = None,
29
+ request_options: typing.Optional[RequestOptions] = None,
30
+ ) -> SyncPager[LseUser]:
31
+ """
32
+ Retrieve the members for a specific workspace.
33
+
34
+ Parameters
35
+ ----------
36
+ id : int
37
+
38
+ ids : typing.Optional[str]
39
+ Comma-separated list of user IDs to filter by
40
+
41
+ page : typing.Optional[int]
42
+ A page number within the paginated result set.
43
+
44
+ page_size : typing.Optional[int]
45
+ Number of results to return per page.
46
+
47
+ search : typing.Optional[str]
48
+ A search term.
49
+
50
+ request_options : typing.Optional[RequestOptions]
51
+ Request-specific configuration.
52
+
53
+ Returns
54
+ -------
55
+ SyncPager[LseUser]
56
+
57
+
58
+ Examples
59
+ --------
60
+ from label_studio_sdk import LabelStudio
61
+
62
+ client = LabelStudio(
63
+ api_key="YOUR_API_KEY",
64
+ )
65
+ response = client.workspaces.members.paginated.list(
66
+ id=1,
67
+ )
68
+ for item in response:
69
+ yield item
70
+ # alternatively, you can paginate page-by-page
71
+ for page in response.iter_pages():
72
+ yield page
73
+ """
74
+ page = page if page is not None else 1
75
+ _response = self._client_wrapper.httpx_client.request(
76
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/paginated/",
77
+ method="GET",
78
+ params={
79
+ "ids": ids,
80
+ "page": page,
81
+ "page_size": page_size,
82
+ "search": search,
83
+ },
84
+ request_options=request_options,
85
+ )
86
+ try:
87
+ if 200 <= _response.status_code < 300:
88
+ _parsed_response = typing.cast(
89
+ PaginatedLseUserList,
90
+ construct_type(
91
+ type_=PaginatedLseUserList, # type: ignore
92
+ object_=_response.json(),
93
+ ),
94
+ )
95
+ _has_next = True
96
+ _get_next = lambda: self.list(
97
+ id,
98
+ ids=ids,
99
+ page=page + 1,
100
+ page_size=page_size,
101
+ search=search,
102
+ request_options=request_options,
103
+ )
104
+ _items = _parsed_response.results
105
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
106
+ _response_json = _response.json()
107
+ except JSONDecodeError:
108
+ raise ApiError(status_code=_response.status_code, body=_response.text)
109
+ raise ApiError(status_code=_response.status_code, body=_response_json)
110
+
111
+
112
+ class AsyncPaginatedClient:
113
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
114
+ self._client_wrapper = client_wrapper
115
+
116
+ async def list(
117
+ self,
118
+ id: int,
119
+ *,
120
+ ids: typing.Optional[str] = None,
121
+ page: typing.Optional[int] = None,
122
+ page_size: typing.Optional[int] = None,
123
+ search: typing.Optional[str] = None,
124
+ request_options: typing.Optional[RequestOptions] = None,
125
+ ) -> AsyncPager[LseUser]:
126
+ """
127
+ Retrieve the members for a specific workspace.
128
+
129
+ Parameters
130
+ ----------
131
+ id : int
132
+
133
+ ids : typing.Optional[str]
134
+ Comma-separated list of user IDs to filter by
135
+
136
+ page : typing.Optional[int]
137
+ A page number within the paginated result set.
138
+
139
+ page_size : typing.Optional[int]
140
+ Number of results to return per page.
141
+
142
+ search : typing.Optional[str]
143
+ A search term.
144
+
145
+ request_options : typing.Optional[RequestOptions]
146
+ Request-specific configuration.
147
+
148
+ Returns
149
+ -------
150
+ AsyncPager[LseUser]
151
+
152
+
153
+ Examples
154
+ --------
155
+ import asyncio
156
+
157
+ from label_studio_sdk import AsyncLabelStudio
158
+
159
+ client = AsyncLabelStudio(
160
+ api_key="YOUR_API_KEY",
161
+ )
162
+
163
+
164
+ async def main() -> None:
165
+ response = await client.workspaces.members.paginated.list(
166
+ id=1,
167
+ )
168
+ async for item in response:
169
+ yield item
170
+ # alternatively, you can paginate page-by-page
171
+ async for page in response.iter_pages():
172
+ yield page
173
+
174
+
175
+ asyncio.run(main())
176
+ """
177
+ page = page if page is not None else 1
178
+ _response = await self._client_wrapper.httpx_client.request(
179
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/paginated/",
180
+ method="GET",
181
+ params={
182
+ "ids": ids,
183
+ "page": page,
184
+ "page_size": page_size,
185
+ "search": search,
186
+ },
187
+ request_options=request_options,
188
+ )
189
+ try:
190
+ if 200 <= _response.status_code < 300:
191
+ _parsed_response = typing.cast(
192
+ PaginatedLseUserList,
193
+ construct_type(
194
+ type_=PaginatedLseUserList, # type: ignore
195
+ object_=_response.json(),
196
+ ),
197
+ )
198
+ _has_next = True
199
+ _get_next = lambda: self.list(
200
+ id,
201
+ ids=ids,
202
+ page=page + 1,
203
+ page_size=page_size,
204
+ search=search,
205
+ request_options=request_options,
206
+ )
207
+ _items = _parsed_response.results
208
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
209
+ _response_json = _response.json()
210
+ except JSONDecodeError:
211
+ raise ApiError(status_code=_response.status_code, body=_response.text)
212
+ raise ApiError(status_code=_response.status_code, body=_response_json)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: label-studio-sdk
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary:
5
5
  Requires-Python: >=3.9,<4
6
6
  Classifier: Intended Audience :: Developers
@@ -29,7 +29,7 @@ Requires-Dist: jsonschema (>=4.23.0)
29
29
  Requires-Dist: lxml (>=4.2.5)
30
30
  Requires-Dist: nltk (>=3.9.1,<4.0.0)
31
31
  Requires-Dist: numpy (>=1.26.4,<3.0.0)
32
- Requires-Dist: opencv-python (>=4.9.0,<5.0.0)
32
+ Requires-Dist: opencv-python (>=4.12.0,<5.0.0)
33
33
  Requires-Dist: pandas (>=0.24.0)
34
34
  Requires-Dist: pydantic (>=1.9.2)
35
35
  Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)