Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ History
All release highlights of this project will be documented in this file.

4.4.39 - November 13, 2025
________________________
__________________________

**Updated**

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
116 changes: 109 additions & 7 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.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.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.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.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 @@ -17,7 +119,7 @@ To create a new "Vector" project with name "Example Project 1" and description


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


To upload all images with extensions "jpg" or "png" from the
Expand All @@ -42,7 +144,7 @@ See the full argument options for


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

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

Expand All @@ -63,7 +165,7 @@ point to that folder with slash after the project name, e.g.,
sa.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:

Expand Down Expand Up @@ -94,7 +196,7 @@ The :file:`classes.json` file will be downloaded to :file:`"<path_to_local_folde


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


The SuperAnnotate format annotation JSONs have the general form:
Expand Down Expand Up @@ -154,7 +256,7 @@ 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:

Expand Down
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ minversion = 3.7
log_cli=true
python_files = test_*.py
;pytest_plugins = ['pytest_profiling']
;addopts = -n 6 --dist loadscope
addopts = -n 6 --dist loadscope
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.4.40dev1"


os.environ.update({"sa_version": __version__})
Expand Down
6 changes: 2 additions & 4 deletions src/superannotate/lib/app/interface/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from lib.core.pydantic_v1 import ErrorWrapper
from lib.core.pydantic_v1 import ValidationError
from lib.infrastructure.controller import Controller
from lib.infrastructure.utils import extract_project_folder
from lib.infrastructure.utils import extract_project_folder_inputs
from lib.infrastructure.validators import wrap_error
from mixpanel import Mixpanel

Expand Down Expand Up @@ -176,9 +176,7 @@ def default_parser(function_name: str, kwargs: dict) -> tuple:
elif value is None:
properties[key] = value
elif key == "project":
properties["project_name"], folder_name = extract_project_folder(value)
if folder_name:
properties["folder_name"] = folder_name
properties.update(extract_project_folder_inputs(value))
elif isinstance(value, (str, int, float, bool)):
properties[key] = value
elif isinstance(value, dict):
Expand Down
Loading