Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,24 @@ History

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

4.4.39 - November 13, 2025
4.5.0 - December 4, 2025
________________________

**Added**

- ``SAClient.remove_users`` Removes users from the team by their email or ID.
- ``SAClient.remove_users_from_project`` Removes users from a specific project by name or ID.

**Updated**

- ``SAClient.get_team_metadata`` Removed users and pending_users keys from the response.
- ``SAClient.clone_project`` Removed users key from the response.
- ``SAClient.get_project_metadata`` Removed users key from the response.


4.4.39 - November 13, 2025
__________________________

**Updated**

- ``SAClient.get_item_by_id`` now supports an optional include parameter to fetch additional fields like custom_metadata and categories.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/api_reference/api_metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Project metadata example:
"creator_id": "admin@superannotate.com",
"updatedAt": "2020-08-31T05:43:43.118Z",
"createdAt": "2020-08-31T05:43:43.118Z"
"type": "Vector",
"type": "Vector", # Pixel, Video, Multimodal
"attachment_name": None,
"attachment_path": None,
"entropy_status": 1,
Expand Down
1 change: 1 addition & 0 deletions docs/source/api_reference/api_project.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ Projects
.. automethod:: superannotate.SAClient.create_categories
.. automethod:: superannotate.SAClient.list_categories
.. automethod:: superannotate.SAClient.remove_categories
.. automethod:: superannotate.SAClient.remove_users_from_project
1 change: 1 addition & 0 deletions docs/source/api_reference/api_team.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Team
.. automethod:: superannotate.SAClient.get_user_metadata
.. automethod:: superannotate.SAClient.set_user_custom_field
.. automethod:: superannotate.SAClient.list_users
.. automethod:: superannotate.SAClient.remove_users
.. automethod:: superannotate.SAClient.pause_user_activity
.. automethod:: superannotate.SAClient.resume_user_activity
.. automethod:: superannotate.SAClient.get_user_scores
Expand Down
12 changes: 6 additions & 6 deletions docs/source/userguide/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ To create a new "Vector" project with name "Example Project 1" and description

project = "Example Project 1"

sa.create_project(project, "test", "Vector")
sa_client.create_project(project, "test", "Vector")

----------

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

.. code-block:: python

sa.upload_images_from_folder_to_project(project, "<local_folder_path>")
sa_client.upload_images_from_folder_to_project(project, "<local_folder_path>")

See the full argument options for
:py:func:`upload_images_from_folder_to_project` :ref:`here <ref_upload_images_from_folder_to_project>`.
Expand Down Expand Up @@ -144,19 +144,19 @@ To download the image one can use:

image = "example_image1.jpg"

sa.download_image(project, image, "<path_to_local_dir>")
sa_client.download_image(project, image, "<path_to_local_dir>")

To download image annotations:

.. code-block:: python

sa.download_image_annotations(project, image, "<path_to_local_dir>")
sa_client.download_image_annotations(project, image, "<path_to_local_dir>")

Upload back to the platform with:

.. code-block:: python

sa.upload_image_annotations(project, image, "<path_to_json>")
sa_client.upload_image_annotations(project, image, "<path_to_json>")

---------

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

.. code-block:: python

sa.invite_contributors_to_team(emails=["admin@superannotate.com"], admin=False)
sa_client.invite_contributors_to_team(emails=["admin@superannotate.com"], admin=False)
136 changes: 119 additions & 17 deletions docs/source/userguide/setup_project.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,110 @@ Setup Project
=============


Creating a project
------------------
Creating a Multimodal project
------------------------------

For Multimodal projects you **must** provide a ``form`` JSON object that
conforms to SuperAnnotate's Multimodal form template schema. The form
defines the project's UI layout and component behavior in the Multimodal
Form Editor.

.. code-block:: python

minimal_form = {
"components": [
{
"id": "component_id_0",
"type": "select",
"permissions": [],
"hasTooltip": False,
"label": "Select",
"isRequired": False,
"value": [],
"options": [
{"value": "Partially complete, needs review", "checked": False},
{"value": "Incomplete", "checked": False},
{"value": "Complete", "checked": False},
{"value": "4", "checked": False}
],
"exclude": False,
"isMultiselect": True,
"placeholder": "Select"
},
{
"id": "component_id_1",
"type": "input",
"permissions": [],
"hasTooltip": False,
"label": "Text input",
"placeholder": "Placeholder",
"isRequired": False,
"value": "",
"min": 0,
"max": 300,
"exclude": False
},
{
"id": "component_id_2",
"type": "number",
"permissions": [],
"hasTooltip": False,
"label": "Number",
"exclude": False,
"isRequired": False,
"value": None,
"min": None,
"max": None,
"step": 1
}
],
"code": "",
"environments": []
}

response = sa_client.create_project(
project_name="My Multimodal Project",
project_description="Example multimodal project created via SDK",
project_type="Multimodal",
form=minimal_form
)

After creating the project, you can create folders and generate items:

.. code-block:: python

# Create a new folder in the project
sa_client.create_folder(
project="My Multimodal Project",
folder_name="First Folder"
)

# Generate multiple items in the specific project and folder
# If there are no items in the folder, it will generate a blank item
# otherwise, it will generate items based on the Custom Form
sa_client.generate_items(
project="My Multimodal Project/First Folder",
count=10,
name="My Item"
)

To upload annotations to these items:

.. code-block:: python

annotations = [
# list of annotation dicts
]

sa_client.upload_annotations(
project="My Multimodal Project/First Folder",
annotations=annotations,
keep_status=True,
data_spec="multimodal"
)

Creating a Vector project
--------------------------

To create a new "Vector" project with name "Example Project 1" and description
"test":
Expand All @@ -13,19 +115,19 @@ To create a new "Vector" project with name "Example Project 1" and description

project = "Example Project 1"

sa.create_project(project, "test", "Vector")
sa_client.create_project(project, "test", "Vector")


Uploading images to project
---------------------------
===========================


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

.. code-block:: python

sa.upload_images_from_folder_to_project(project, "<local_folder_path>")
sa_client.upload_images_from_folder_to_project(project, "<local_folder_path>")

See the full argument options for
:py:func:`upload_images_from_folder_to_project` :ref:`here <ref_upload_images_from_folder_to_project>`.
Expand All @@ -42,13 +144,13 @@ See the full argument options for


Creating a folder in a project
______________________________
==============================

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

.. code-block:: python

sa.create_folder(project, "folder1")
sa_client.create_folder(project, "folder1")

After that point almost all SDK functions that use project name as argument can
point to that folder with slash after the project name, e.g.,
Expand All @@ -60,16 +162,16 @@ point to that folder with slash after the project name, e.g.,

.. code-block:: python

sa.upload_images_from_folder_to_project(project + "/folder1", "<local_folder_path>")
sa_client.upload_images_from_folder_to_project(project + "/folder1", "<local_folder_path>")

Working with annotation classes
_______________________________
===============================

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

.. code-block:: python

sa.create_annotation_class(project, "Large car", color="#FFFFAA")
sa_client.create_annotation_class(project, "Large car", color="#FFFFAA")


To create annotation classes in bulk with SuperAnnotate export format
Expand All @@ -79,7 +181,7 @@ https://superannotate.readthedocs.io/en/stable/userguide/setup_project.html#work

.. code-block:: python

sa.create_annotation_classes_from_classes_json(project, "<path_to_classes_json>")
sa_client.create_annotation_classes_from_classes_json(project, "<path_to_classes_json>")


All of the annotation classes of a project are downloaded (as :file:`classes/classes.json`) with
Expand All @@ -88,13 +190,13 @@ can also be downloaded separately with:

.. code-block:: python

sa.download_annotation_classes_json(project, "<path_to_local_folder>")
sa_client.download_annotation_classes_json(project, "<path_to_local_folder>")

The :file:`classes.json` file will be downloaded to :file:`"<path_to_local_folder>"` folder.


Working with annotations
________________________
========================


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

.. code-block:: python

sa.upload_annotations_from_folder_to_project(project, "<path_to_local_dir>")
sa_client.upload_annotations_from_folder_to_project(project, "<path_to_local_dir>")


This will try uploading to the project all the JSON files in the folder that have :file:`"<image_name>.json"` postfix.
Expand All @@ -154,19 +256,19 @@ already be present in the project for the upload to work.


Exporting projects
__________________
==================

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

.. code-block:: python

export = sa.prepare_export(project, include_fuse=True)
export = sa_client.prepare_export(project, include_fuse=True)

We can download the prepared export with:

.. code-block:: python

sa.download_export(project, export, "<local_folder_path>", extract_zip_contents=True)
sa_client.download_export(project, export, "<local_folder_path>", extract_zip_contents=True)

:ref:`download_export <ref_download_export>` will wait until the export is
finished preparing and download it to the specified folder.
14 changes: 7 additions & 7 deletions docs/source/userguide/utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ to convert them to other annotation formats:

.. code-block:: python

sa.export_annotation("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
sa_client.export_annotation("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
"<project_type>", "<task>")

.. note::
Expand Down Expand Up @@ -197,10 +197,10 @@ Example Python Script:
csv_to_jsonl("annotations.csv", "annotations.jsonl")

# Upload to SuperAnnotate
sa = SAClient()
sa_client = SAClient()
annotations = [json.loads(line) for line in Path("annotations.jsonl").open("r", encoding="utf-8")]

response = sa.upload_annotations(
response = sa_client.upload_annotations(
project="project1/folder1",
annotations=annotations,
keep_status=True,
Expand All @@ -214,7 +214,7 @@ Fetching Annotations and Converting to JSONL/CSV
Steps to Retrieve and Convert Annotations:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Expand All @@ -230,8 +230,8 @@ Python Script to Convert Annotations to JSONL:
jsonl_file.write('\n')

# Fetch annotations from SuperAnnotate
sa = SAClient()
annotations = sa.get_annotations("project", data_spec="multimodal")
sa_client = SAClient()
annotations = sa_client.get_annotations("project", data_spec="multimodal")

# Convert to JSONL
convert_annotations_to_jsonl(annotations, "fetched_annotations.jsonl")
Expand Down Expand Up @@ -284,7 +284,7 @@ SuperAnnotate format annotations:

.. code-block:: python

df = sa.aggregate_annotations_as_df("<path_to_project_folder>")
df = sa_client.aggregate_annotations_as_df("<path_to_project_folder>")

The created DataFrame will have columns specified at
:ref:`aggregate_annotations_as_df <ref_aggregate_annotations_as_df>`.
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pydantic>=1.10,!=2.0.*
pydantic>=1.10,<3,!=2.0.*
aiohttp~=3.8
boto3~=1.26
opencv-python-headless~=4.7
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys


__version__ = "4.4.39"
__version__ = "4.5.0dev1"


os.environ.update({"sa_version": __version__})
Expand Down
Loading