Skip to content

Commit 5c8e2ed

Browse files
authored
Merge pull request #455 from superannotateai/doc_updates
Updated the docs
2 parents 76f9dd8 + b8171ff commit 5c8e2ed

File tree

14 files changed

+49
-188
lines changed

14 files changed

+49
-188
lines changed

docs/source/index.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ SuperAnnotate Python SDK allows access to the platform without web browser:
2929

3030
.. code-block:: python
3131
32-
import superannotate as sa
32+
from superannotate import SAClient
33+
34+
sa = SAClient()
3335
3436
sa.create_project("Example Project 1", "example", "Vector")
3537

docs/source/superannotate.sdk.rst

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ API Reference
88
Remote functions
99
----------------
1010

11-
Initialization and authentication
11+
Instantiation and authentication
1212
_________________________________
1313

14-
.. automethod:: superannotate.SAClient.__init__
14+
.. autoclass:: superannotate.SAClient
1515

1616

17-
.. _ref_projects:
18-
1917
Projects
2018
________
2119

@@ -93,8 +91,6 @@ ______
9391

9492
.. _ref_search_images:
9593
.. automethod:: superannotate.SAClient.download_image
96-
.. automethod:: superannotate.SAClient.set_image_annotation_status
97-
.. automethod:: superannotate.SAClient.set_images_annotation_statuses
9894
.. automethod:: superannotate.SAClient.download_image_annotations
9995
.. automethod:: superannotate.SAClient.upload_image_annotations
10096
.. automethod:: superannotate.SAClient.copy_image

docs/source/tutorial.sdk.rst

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ Include the package in your Python code:
7777

7878
.. code-block:: python
7979
80-
import superannotate as sa
80+
from superannotate import SAClient
8181
8282
SDK is ready to be used if default location config file was created using
8383
the :ref:`CLI init <ref_cli_init>`. Otherwise to authenticate SDK with the :ref:`custom config file <ref_custom_config_file>`:
8484

8585
.. code-block:: python
8686
87-
sa.init("<path_to_config_json>")
87+
sa = SAClient(config_path="<path_to_config_json>")
8888
8989
Creating a project
9090
____________________________
@@ -273,80 +273,81 @@ You can find more information annotation format conversion :ref:`here <ref_conve
273273

274274
.. code-block:: python
275275
276-
import superannotate as sa
276+
from superannotate import export_annotation
277+
from superannotate import import_annotation
277278
278279
# From SA format to COCO panoptic format
279-
sa.export_annotation(
280+
export_annotation(
280281
"tests/converter_test/COCO/input/fromSuperAnnotate/cats_dogs_panoptic_segm",
281282
"tests/converter_test/COCO/output/panoptic",
282283
"COCO", "panoptic_test", "Pixel","panoptic_segmentation"
283284
)
284285
285286
# From COCO keypoints detection format to SA annotation format
286-
sa.import_annotation(
287+
import_annotation(
287288
"tests/converter_test/COCO/input/toSuperAnnotate/keypoint_detection",
288289
"tests/converter_test/COCO/output/keypoints",
289290
"COCO", "person_keypoints_test", "Vector", "keypoint_detection"
290291
)
291292
292293
# Pascal VOC annotation format to SA annotation format
293-
sa.import_annotation(
294+
import_annotation(
294295
"tests/converter_test/VOC/input/fromPascalVOCToSuperAnnotate/VOC2012",
295296
"tests/converter_test/VOC/output/instances",
296297
"VOC", "instances_test", "Pixel", "instance_segmentation"
297298
)
298299
299300
# YOLO annotation format to SA annotation format
300-
sa.import_annotation(
301+
import_annotation(
301302
'tests/converter_test/YOLO/input/toSuperAnnotate',
302303
'tests/converter_test/YOLO/output',
303304
'YOLO', '', 'Vector', 'object_detection'
304305
)
305306
306307
# LabelBox annotation format to SA annotation format
307-
sa.import_annotation(
308+
import_annotation(
308309
"tests/converter_test/LabelBox/input/toSuperAnnotate/",
309310
"tests/converter_test/LabelBox/output/objects/",
310311
"LabelBox", "labelbox_example", "Vector", "object_detection"
311312
)
312313
313314
# Supervisely annotation format to SA annotation format
314-
sa.import_annotation(
315+
import_annotation(
315316
"tests/converter_test/Supervisely/input/toSuperAnnotate",
316317
"tests/converter_test/Supervisely/output",
317318
"Supervisely", "", "Vector", "vector_annotation"
318319
)
319320
320321
# DataLoop annotation format to SA annotation format
321-
sa.import_annotation(
322+
import_annotation(
322323
"tests/converter_test/DataLoop/input/toSuperAnnotate",
323324
"tests/converter_test/DataLoop/output",
324325
"DataLoop", "", "Vector", "vector_annotation"
325326
)
326327
327328
# VGG annotation format to SA annotation format
328-
sa.import_annotation(
329+
import_annotation(
329330
"tests/converter_test/VGG/input/toSuperAnnotate",
330331
"tests/converter_test/VGG/output",
331332
"VGG", "vgg_test", "Vector", "instance_segmentation"
332333
)
333334
334335
# VoTT annotation format to SA annotation format
335-
sa.import_annotation(
336+
import_annotation(
336337
"tests/converter_test/VoTT/input/toSuperAnnotate",
337338
"tests/converter_test/VoTT/output",
338339
"VoTT", "", "Vector", "vector_annotation"
339340
)
340341
341342
# GoogleCloud annotation format to SA annotation format
342-
sa.import_annotation(
343+
import_annotation(
343344
"tests/converter_test/GoogleCloud/input/toSuperAnnotate",
344345
"tests/converter_test/GoogleCloud/output",
345346
"GoogleCloud", "image_object_detection", "Vector", "object_detection"
346347
)
347348
348349
# GoogleCloud annotation format to SA annotation format
349-
sa.import_annotation(
350+
import_annotation(
350351
"tests/converter_test/SageMaker/input/toSuperAnnotate",
351352
"tests/converter_test/SageMaker/output",
352353
"SageMaker", "test-obj-detect", "Vector", "object_detection"

requirements_dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
superannotate_schemas>=v1.0.43dev5
1+
superannotate_schemas>=v1.0.45dev1
22

src/superannotate/lib/app/interface/sdk_interface.py

Lines changed: 14 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@
6262

6363

6464
class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
65+
"""Create SAClient instance to authorize SDK in a team scope.
66+
In case of no argument has been provided, SA_TOKEN environmental variable
67+
will be checked or $HOME/.superannotate/config.json will be used.
68+
69+
:param token: team token
70+
:type token: str
71+
72+
:param config_path: path to config file
73+
:type config_path: path-like (str or Path)
74+
75+
"""
76+
6577
def __init__(
6678
self,
6779
token: str = None,
@@ -618,37 +630,6 @@ def pin_image(
618630
is_pinned=int(pin),
619631
)
620632

621-
def set_images_annotation_statuses(
622-
self,
623-
project: Union[NotEmptyStr, dict],
624-
annotation_status: NotEmptyStr,
625-
image_names: Optional[List[NotEmptyStr]] = None,
626-
):
627-
"""Sets annotation statuses of images
628-
629-
:param project: project name or folder path (e.g., "project1/folder1")
630-
:type project: str
631-
:param image_names: image names. If None, all the images in the project will be used
632-
:type image_names: list of str
633-
:param annotation_status: annotation status to set,
634-
should be one of NotStarted InProgress QualityCheck Returned Completed Skipped
635-
:type annotation_status: str
636-
"""
637-
warning_msg = (
638-
"We're deprecating the set_images_annotation_statuses function. Please use set_annotation_statuses instead. "
639-
"Learn more. \n"
640-
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.set_annotation_statuses"
641-
)
642-
logger.warning(warning_msg)
643-
warnings.warn(warning_msg, DeprecationWarning)
644-
project_name, folder_name = extract_project_folder(project)
645-
response = self.controller.set_images_annotation_statuses(
646-
project_name, folder_name, image_names, annotation_status
647-
)
648-
if response.errors:
649-
raise AppException(response.errors)
650-
logger.info("Annotations status of images changed")
651-
652633
def delete_images(
653634
self, project: Union[NotEmptyStr, dict], image_names: Optional[List[str]] = None
654635
):
@@ -682,9 +663,7 @@ def delete_images(
682663
f"Images deleted in project {project_name}{'/' + folder_name if folder_name else ''}"
683664
)
684665

685-
def delete_items(
686-
self, project: str, items: Optional[List[str]] = None
687-
):
666+
def delete_items(self, project: str, items: Optional[List[str]] = None):
688667
"""Delete items in a given project.
689668
690669
:param project: project name or folder path (e.g., "project1/folder1")
@@ -700,7 +679,6 @@ def delete_items(
700679
if response.errors:
701680
raise AppException(response.errors)
702681

703-
704682
def assign_items(
705683
self, project: Union[NotEmptyStr, dict], items: List[str], user: str
706684
):
@@ -1427,41 +1405,6 @@ def download_export(
14271405
raise AppException(response.errors)
14281406
logger.info(response.data)
14291407

1430-
def set_image_annotation_status(
1431-
self,
1432-
project: Union[NotEmptyStr, dict],
1433-
image_name: NotEmptyStr,
1434-
annotation_status: NotEmptyStr,
1435-
):
1436-
"""Sets the image annotation status
1437-
1438-
:param project: project name or folder path (e.g., "project1/folder1")
1439-
:type project: str
1440-
:param image_name: image name
1441-
:type image_name: str
1442-
:param annotation_status: annotation status to set,
1443-
should be one of NotStarted InProgress QualityCheck Returned Completed Skipped
1444-
:type annotation_status: str
1445-
1446-
:return: metadata of the updated image
1447-
:rtype: dict
1448-
"""
1449-
warning_msg = (
1450-
"We're deprecating the set_image_annotation_status function. Please use set_annotation_statuses instead. "
1451-
"Learn more. \n"
1452-
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.set_annotation_statuses"
1453-
)
1454-
logger.warning(warning_msg)
1455-
warnings.warn(warning_msg, DeprecationWarning)
1456-
project_name, folder_name = extract_project_folder(project)
1457-
response = self.controller.set_images_annotation_statuses(
1458-
project_name, folder_name, [image_name], annotation_status
1459-
)
1460-
if response.errors:
1461-
raise AppException(response.errors)
1462-
image = self.controller.get_item(project_name, folder_name, image_name).data
1463-
return BaseSerializer(image).serialize()
1464-
14651408
def set_project_workflow(
14661409
self, project: Union[NotEmptyStr, dict], new_workflow: List[dict]
14671410
):
@@ -1720,7 +1663,7 @@ def download_model(self, model: MLModel, output_dir: Union[str, Path]):
17201663
17211664
:param model: the model that needs to be downloaded
17221665
:type model: dict
1723-
:param output_dir: the directiory in which the files will be saved
1666+
:param output_dir: the directory in which the files will be saved
17241667
:type output_dir: str
17251668
:return: the metadata of the model
17261669
:rtype: dict

src/superannotate/lib/core/usecases/images.py

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,61 +2063,6 @@ def execute(self):
20632063
return self._response
20642064

20652065

2066-
class SetImageAnnotationStatuses(BaseUseCase):
2067-
CHUNK_SIZE = 500
2068-
2069-
def __init__(
2070-
self,
2071-
service: SuperannotateServiceProvider,
2072-
projects: BaseReadOnlyRepository,
2073-
image_names: list,
2074-
team_id: int,
2075-
project_id: int,
2076-
folder_id: int,
2077-
images_repo: BaseManageableRepository,
2078-
annotation_status: int,
2079-
):
2080-
super().__init__()
2081-
self._service = service
2082-
self._projects = projects
2083-
self._image_names = image_names
2084-
self._team_id = team_id
2085-
self._project_id = project_id
2086-
self._folder_id = folder_id
2087-
self._annotation_status = annotation_status
2088-
self._images_repo = images_repo
2089-
2090-
def validate_project_type(self):
2091-
project = self._projects.get_one(uuid=self._project_id, team_id=self._team_id)
2092-
if project.type in constances.LIMITED_FUNCTIONS:
2093-
raise AppValidationException(constances.LIMITED_FUNCTIONS[project.type])
2094-
2095-
def execute(self):
2096-
if self.is_valid():
2097-
if self._image_names is None:
2098-
condition = (
2099-
Condition("team_id", self._team_id, EQ)
2100-
& Condition("project_id", self._project_id, EQ)
2101-
& Condition("folder_id", self._folder_id, EQ)
2102-
)
2103-
self._image_names = [
2104-
image.name for image in self._images_repo.get_all(condition)
2105-
]
2106-
for i in range(0, len(self._image_names), self.CHUNK_SIZE):
2107-
status_changed = self._service.set_images_statuses_bulk(
2108-
image_names=self._image_names[
2109-
i : i + self.CHUNK_SIZE # noqa: E203
2110-
],
2111-
team_id=self._team_id,
2112-
project_id=self._project_id,
2113-
folder_id=self._folder_id,
2114-
annotation_status=self._annotation_status,
2115-
)
2116-
if not status_changed:
2117-
self._response.errors = AppException("Failed to change status.")
2118-
return self._response
2119-
2120-
21212066
class CreateAnnotationClassUseCase(BaseUseCase):
21222067
def __init__(
21232068
self,

src/superannotate/lib/core/usecases/items.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from lib.core.entities import DocumentEntity
1010
from lib.core.entities import Entity
1111
from lib.core.entities import FolderEntity
12+
from lib.core.entities import ImageEntity
1213
from lib.core.entities import ProjectEntity
1314
from lib.core.entities import SubSetEntity
1415
from lib.core.entities import TmpImageEntity
@@ -22,11 +23,11 @@
2223
from lib.core.serviceproviders import SuperannotateServiceProvider
2324
from lib.core.usecases.base import BaseReportableUseCase
2425
from lib.core.usecases.base import BaseUseCase
25-
from lib.core.entities import ImageEntity
2626
from superannotate.logger import get_default_logger
2727

2828
logger = get_default_logger()
2929

30+
3031
class GetBulkItems(BaseUseCase):
3132
def __init__(
3233
self,
@@ -56,11 +57,12 @@ def execute(self):
5657

5758
if not response.ok:
5859
raise AppException(response.error)
59-
#TODO stop using Image Entity when it gets deprecated and from_dict gets implemented for items
60+
# TODO stop using Image Entity when it gets deprecated and from_dict gets implemented for items
6061
res += [ImageEntity.from_dict(**item) for item in response.data]
6162
self._response.data = res
6263
return self._response
6364

65+
6466
class GetItem(BaseReportableUseCase):
6567
def __init__(
6668
self,
@@ -133,7 +135,7 @@ def __init__(
133135

134136
def validate_query(self):
135137
if self._project.sync_status != constants.ProjectState.SYNCED.value:
136-
raise AppException("Data is not synced.")
138+
raise AppException("Project data is not synced.")
137139
if self._query:
138140
response = self._backend_client.validate_saqul_query(
139141
self._project.team_id, self._project.id, self._query
@@ -722,6 +724,7 @@ def execute(self):
722724
break
723725
return self._response
724726

727+
725728
class DeleteItemsUseCase(BaseUseCase):
726729
CHUNK_SIZE = 1000
727730

0 commit comments

Comments
 (0)