Skip to content

Commit 42a009d

Browse files
authored
Merge pull request #820 from superannotateai/develop
Develop
2 parents 24ac1f1 + a5d9fc7 commit 42a009d

File tree

24 files changed

+561
-299
lines changed

24 files changed

+561
-299
lines changed

CHANGELOG.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,24 @@ History
66

77
All release highlights of this project will be documented in this file.
88

9-
4.4.39 - November 13, 2025
9+
4.5.0 - December 4, 2025
1010
________________________
1111

12+
**Added**
13+
14+
- ``SAClient.remove_users`` Removes users from the team by their email or ID.
15+
- ``SAClient.remove_users_from_project`` Removes users from a specific project by name or ID.
16+
17+
**Updated**
18+
19+
- ``SAClient.get_team_metadata`` Removed users and pending_users keys from the response.
20+
- ``SAClient.clone_project`` Removed users key from the response.
21+
- ``SAClient.get_project_metadata`` Removed users key from the response.
22+
23+
24+
4.4.39 - November 13, 2025
25+
__________________________
26+
1227
**Updated**
1328

1429
- ``SAClient.get_item_by_id`` now supports an optional include parameter to fetch additional fields like custom_metadata and categories.

docs/source/api_reference/api_metadata.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Project metadata example:
1818
"creator_id": "admin@superannotate.com",
1919
"updatedAt": "2020-08-31T05:43:43.118Z",
2020
"createdAt": "2020-08-31T05:43:43.118Z"
21-
"type": "Vector",
21+
"type": "Vector", # Pixel, Video, Multimodal
2222
"attachment_name": None,
2323
"attachment_path": None,
2424
"entropy_status": 1,

docs/source/api_reference/api_project.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ Projects
3030
.. automethod:: superannotate.SAClient.create_categories
3131
.. automethod:: superannotate.SAClient.list_categories
3232
.. automethod:: superannotate.SAClient.remove_categories
33+
.. automethod:: superannotate.SAClient.remove_users_from_project

docs/source/api_reference/api_team.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Team
1111
.. automethod:: superannotate.SAClient.get_user_metadata
1212
.. automethod:: superannotate.SAClient.set_user_custom_field
1313
.. automethod:: superannotate.SAClient.list_users
14+
.. automethod:: superannotate.SAClient.remove_users
1415
.. automethod:: superannotate.SAClient.pause_user_activity
1516
.. automethod:: superannotate.SAClient.resume_user_activity
1617
.. automethod:: superannotate.SAClient.get_user_scores

docs/source/userguide/quickstart.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ To create a new "Vector" project with name "Example Project 1" and description
101101
102102
project = "Example Project 1"
103103
104-
sa.create_project(project, "test", "Vector")
104+
sa_client.create_project(project, "test", "Vector")
105105
106106
----------
107107

@@ -115,7 +115,7 @@ To upload all images with extensions "jpg" or "png" from the
115115

116116
.. code-block:: python
117117
118-
sa.upload_images_from_folder_to_project(project, "<local_folder_path>")
118+
sa_client.upload_images_from_folder_to_project(project, "<local_folder_path>")
119119
120120
See the full argument options for
121121
:py:func:`upload_images_from_folder_to_project` :ref:`here <ref_upload_images_from_folder_to_project>`.
@@ -144,19 +144,19 @@ To download the image one can use:
144144
145145
image = "example_image1.jpg"
146146
147-
sa.download_image(project, image, "<path_to_local_dir>")
147+
sa_client.download_image(project, image, "<path_to_local_dir>")
148148
149149
To download image annotations:
150150

151151
.. code-block:: python
152152
153-
sa.download_image_annotations(project, image, "<path_to_local_dir>")
153+
sa_client.download_image_annotations(project, image, "<path_to_local_dir>")
154154
155155
Upload back to the platform with:
156156

157157
.. code-block:: python
158158
159-
sa.upload_image_annotations(project, image, "<path_to_json>")
159+
sa_client.upload_image_annotations(project, image, "<path_to_json>")
160160
161161
---------
162162

@@ -168,4 +168,4 @@ A team contributor can be invited to the team with:
168168

169169
.. code-block:: python
170170
171-
sa.invite_contributors_to_team(emails=["admin@superannotate.com"], admin=False)
171+
sa_client.invite_contributors_to_team(emails=["admin@superannotate.com"], admin=False)

docs/source/userguide/setup_project.rst

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,110 @@ Setup Project
33
=============
44

55

6-
Creating a project
7-
------------------
6+
Creating a Multimodal project
7+
------------------------------
8+
9+
For Multimodal projects you **must** provide a ``form`` JSON object that
10+
conforms to SuperAnnotate's Multimodal form template schema. The form
11+
defines the project's UI layout and component behavior in the Multimodal
12+
Form Editor.
13+
14+
.. code-block:: python
15+
16+
minimal_form = {
17+
"components": [
18+
{
19+
"id": "component_id_0",
20+
"type": "select",
21+
"permissions": [],
22+
"hasTooltip": False,
23+
"label": "Select",
24+
"isRequired": False,
25+
"value": [],
26+
"options": [
27+
{"value": "Partially complete, needs review", "checked": False},
28+
{"value": "Incomplete", "checked": False},
29+
{"value": "Complete", "checked": False},
30+
{"value": "4", "checked": False}
31+
],
32+
"exclude": False,
33+
"isMultiselect": True,
34+
"placeholder": "Select"
35+
},
36+
{
37+
"id": "component_id_1",
38+
"type": "input",
39+
"permissions": [],
40+
"hasTooltip": False,
41+
"label": "Text input",
42+
"placeholder": "Placeholder",
43+
"isRequired": False,
44+
"value": "",
45+
"min": 0,
46+
"max": 300,
47+
"exclude": False
48+
},
49+
{
50+
"id": "component_id_2",
51+
"type": "number",
52+
"permissions": [],
53+
"hasTooltip": False,
54+
"label": "Number",
55+
"exclude": False,
56+
"isRequired": False,
57+
"value": None,
58+
"min": None,
59+
"max": None,
60+
"step": 1
61+
}
62+
],
63+
"code": "",
64+
"environments": []
65+
}
66+
67+
response = sa_client.create_project(
68+
project_name="My Multimodal Project",
69+
project_description="Example multimodal project created via SDK",
70+
project_type="Multimodal",
71+
form=minimal_form
72+
)
73+
74+
After creating the project, you can create folders and generate items:
75+
76+
.. code-block:: python
77+
78+
# Create a new folder in the project
79+
sa_client.create_folder(
80+
project="My Multimodal Project",
81+
folder_name="First Folder"
82+
)
83+
84+
# Generate multiple items in the specific project and folder
85+
# If there are no items in the folder, it will generate a blank item
86+
# otherwise, it will generate items based on the Custom Form
87+
sa_client.generate_items(
88+
project="My Multimodal Project/First Folder",
89+
count=10,
90+
name="My Item"
91+
)
92+
93+
To upload annotations to these items:
94+
95+
.. code-block:: python
96+
97+
annotations = [
98+
# list of annotation dicts
99+
]
100+
101+
sa_client.upload_annotations(
102+
project="My Multimodal Project/First Folder",
103+
annotations=annotations,
104+
keep_status=True,
105+
data_spec="multimodal"
106+
)
107+
108+
Creating a Vector project
109+
--------------------------
8110

9111
To create a new "Vector" project with name "Example Project 1" and description
10112
"test":
@@ -13,19 +115,19 @@ To create a new "Vector" project with name "Example Project 1" and description
13115
14116
project = "Example Project 1"
15117
16-
sa.create_project(project, "test", "Vector")
118+
sa_client.create_project(project, "test", "Vector")
17119
18120
19121
Uploading images to project
20-
---------------------------
122+
===========================
21123

22124

23125
To upload all images with extensions "jpg" or "png" from the
24126
:file:`"<local_folder_path>"` to the project "Example Project 1":
25127

26128
.. code-block:: python
27129
28-
sa.upload_images_from_folder_to_project(project, "<local_folder_path>")
130+
sa_client.upload_images_from_folder_to_project(project, "<local_folder_path>")
29131
30132
See the full argument options for
31133
:py:func:`upload_images_from_folder_to_project` :ref:`here <ref_upload_images_from_folder_to_project>`.
@@ -42,13 +144,13 @@ See the full argument options for
42144

43145

44146
Creating a folder in a project
45-
______________________________
147+
==============================
46148

47149
To create a new folder "folder1" in the project "Example Project 1":
48150

49151
.. code-block:: python
50152
51-
sa.create_folder(project, "folder1")
153+
sa_client.create_folder(project, "folder1")
52154
53155
After that point almost all SDK functions that use project name as argument can
54156
point to that folder with slash after the project name, e.g.,
@@ -60,16 +162,16 @@ point to that folder with slash after the project name, e.g.,
60162

61163
.. code-block:: python
62164
63-
sa.upload_images_from_folder_to_project(project + "/folder1", "<local_folder_path>")
165+
sa_client.upload_images_from_folder_to_project(project + "/folder1", "<local_folder_path>")
64166
65167
Working with annotation classes
66-
_______________________________
168+
===============================
67169

68170
An annotation class for a project can be created with SDK's:
69171

70172
.. code-block:: python
71173
72-
sa.create_annotation_class(project, "Large car", color="#FFFFAA")
174+
sa_client.create_annotation_class(project, "Large car", color="#FFFFAA")
73175
74176
75177
To create annotation classes in bulk with SuperAnnotate export format
@@ -79,7 +181,7 @@ https://superannotate.readthedocs.io/en/stable/userguide/setup_project.html#work
79181

80182
.. code-block:: python
81183
82-
sa.create_annotation_classes_from_classes_json(project, "<path_to_classes_json>")
184+
sa_client.create_annotation_classes_from_classes_json(project, "<path_to_classes_json>")
83185
84186
85187
All of the annotation classes of a project are downloaded (as :file:`classes/classes.json`) with
@@ -88,13 +190,13 @@ can also be downloaded separately with:
88190

89191
.. code-block:: python
90192
91-
sa.download_annotation_classes_json(project, "<path_to_local_folder>")
193+
sa_client.download_annotation_classes_json(project, "<path_to_local_folder>")
92194
93195
The :file:`classes.json` file will be downloaded to :file:`"<path_to_local_folder>"` folder.
94196

95197

96198
Working with annotations
97-
________________________
199+
========================
98200

99201

100202
The SuperAnnotate format annotation JSONs have the general form:
@@ -143,7 +245,7 @@ you are uploading to should contain annotation class with that name.
143245

144246
.. code-block:: python
145247
146-
sa.upload_annotations_from_folder_to_project(project, "<path_to_local_dir>")
248+
sa_client.upload_annotations_from_folder_to_project(project, "<path_to_local_dir>")
147249
148250
149251
This will try uploading to the project all the JSON files in the folder that have :file:`"<image_name>.json"` postfix.
@@ -154,19 +256,19 @@ already be present in the project for the upload to work.
154256

155257

156258
Exporting projects
157-
__________________
259+
==================
158260

159261
To export the project annotations we need to prepare the export first:
160262

161263
.. code-block:: python
162264
163-
export = sa.prepare_export(project, include_fuse=True)
265+
export = sa_client.prepare_export(project, include_fuse=True)
164266
165267
We can download the prepared export with:
166268

167269
.. code-block:: python
168270
169-
sa.download_export(project, export, "<local_folder_path>", extract_zip_contents=True)
271+
sa_client.download_export(project, export, "<local_folder_path>", extract_zip_contents=True)
170272
171273
:ref:`download_export <ref_download_export>` will wait until the export is
172274
finished preparing and download it to the specified folder.

docs/source/userguide/utilities.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ to convert them to other annotation formats:
2020

2121
.. code-block:: python
2222
23-
sa.export_annotation("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
23+
sa_client.export_annotation("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
2424
"<project_type>", "<task>")
2525
2626
.. note::
@@ -197,10 +197,10 @@ Example Python Script:
197197
csv_to_jsonl("annotations.csv", "annotations.jsonl")
198198
199199
# Upload to SuperAnnotate
200-
sa = SAClient()
200+
sa_client = SAClient()
201201
annotations = [json.loads(line) for line in Path("annotations.jsonl").open("r", encoding="utf-8")]
202202
203-
response = sa.upload_annotations(
203+
response = sa_client.upload_annotations(
204204
project="project1/folder1",
205205
annotations=annotations,
206206
keep_status=True,
@@ -214,7 +214,7 @@ Fetching Annotations and Converting to JSONL/CSV
214214
Steps to Retrieve and Convert Annotations:
215215
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
216216

217-
1. Fetch **annotations from SuperAnnotate** using `sa.get_annotations()`.
217+
1. Fetch **annotations from SuperAnnotate** using `sa_client.get_annotations()`.
218218
2. Convert the **annotation list into JSONL format**.
219219
3. Convert the **JSONL data into CSV** for external use.
220220

@@ -230,8 +230,8 @@ Python Script to Convert Annotations to JSONL:
230230
jsonl_file.write('\n')
231231
232232
# Fetch annotations from SuperAnnotate
233-
sa = SAClient()
234-
annotations = sa.get_annotations("project", data_spec="multimodal")
233+
sa_client = SAClient()
234+
annotations = sa_client.get_annotations("project", data_spec="multimodal")
235235
236236
# Convert to JSONL
237237
convert_annotations_to_jsonl(annotations, "fetched_annotations.jsonl")
@@ -284,7 +284,7 @@ SuperAnnotate format annotations:
284284

285285
.. code-block:: python
286286
287-
df = sa.aggregate_annotations_as_df("<path_to_project_folder>")
287+
df = sa_client.aggregate_annotations_as_df("<path_to_project_folder>")
288288
289289
The created DataFrame will have columns specified at
290290
:ref:`aggregate_annotations_as_df <ref_aggregate_annotations_as_df>`.

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pydantic>=1.10,!=2.0.*
1+
pydantic>=1.10,<3,!=2.0.*
22
aiohttp~=3.8
33
boto3~=1.26
44
opencv-python-headless~=4.7

src/superannotate/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44

55

6-
__version__ = "4.4.39"
6+
__version__ = "4.5.0dev1"
77

88

99
os.environ.update({"sa_version": __version__})

0 commit comments

Comments
 (0)