Skip to content

Commit 96c2505

Browse files
authored
Merge pull request #362 from superannotateai/develop
Develop
2 parents 19f16c6 + 52f13e4 commit 96c2505

35 files changed

+735
-262
lines changed

docs/source/cli.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ Only when COCO format is specified *dataset-name* and *task* arguments are requi
148148
*task* specifies the COCO task for conversion. Please see
149149
:ref:`import_annotation_format <ref_import_annotation_format>` for more details.
150150
151-
The annotation classes will be created during the execution of this command.
152151
153152
----------
154153
@@ -176,8 +175,6 @@ Only when COCO format is specified *dataset-name* and *task* arguments are requi
176175
*task* specifies the COCO task for conversion. Please see
177176
:ref:`import_annotation_format <ref_import_annotation_format>` for more details.
178177

179-
The annotation classes will be created during the execution of this command.
180-
181178
----------
182179

183180
.. _ref_export_project:

docs/source/superannotate.sdk.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ ________
4949
.. autofunction:: superannotate.upload_annotations_from_folder_to_project
5050
.. autofunction:: superannotate.upload_preannotations_from_folder_to_project
5151
.. autofunction:: superannotate.share_project
52+
.. autofunction:: superannotate.add_contributors_to_project
5253
.. autofunction:: superannotate.get_project_settings
5354
.. autofunction:: superannotate.set_project_default_image_quality_in_editor
5455
.. autofunction:: superannotate.get_project_workflow
@@ -108,7 +109,7 @@ Team contributors
108109
_________________
109110

110111
.. autofunction:: superannotate.get_team_metadata
111-
.. autofunction:: superannotate.invite_contributor_to_team
112+
.. autofunction:: superannotate.invite_contributors_to_team
112113
.. autofunction:: superannotate.search_team_contributors
113114

114115
----------

docs/source/tutorial.sdk.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ A team contributor can be invited to the team with:
388388

389389
.. code-block:: python
390390
391-
sa.invite_contributor_to_team(email="hovnatan@superannotate.com", admin=False)
391+
sa.invite_contributors_to_team(emails=["hovnatan@superannotate.com"], admin=False)
392392
393393
394394
This invitation should be accepted by the contributor. After which, to share the

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
minversion = 3.0
33
log_cli=true
44
python_files = test_*.py
5-
addopts = -n auto --dist=loadscope
5+
;addopts = -n auto --dist=lo adscope

src/superannotate/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
add_annotation_comment_to_image,
1818
)
1919
from superannotate.lib.app.interface.sdk_interface import add_annotation_point_to_image
20+
from superannotate.lib.app.interface.sdk_interface import add_contributors_to_project
2021
from superannotate.lib.app.interface.sdk_interface import aggregate_annotations_as_df
2122
from superannotate.lib.app.interface.sdk_interface import assign_folder
2223
from superannotate.lib.app.interface.sdk_interface import assign_images
@@ -63,7 +64,7 @@
6364
from superannotate.lib.app.interface.sdk_interface import get_project_workflow
6465
from superannotate.lib.app.interface.sdk_interface import get_team_metadata
6566
from superannotate.lib.app.interface.sdk_interface import init
66-
from superannotate.lib.app.interface.sdk_interface import invite_contributor_to_team
67+
from superannotate.lib.app.interface.sdk_interface import invite_contributors_to_team
6768
from superannotate.lib.app.interface.sdk_interface import move_images
6869
from superannotate.lib.app.interface.sdk_interface import pin_image
6970
from superannotate.lib.app.interface.sdk_interface import prepare_export
@@ -128,7 +129,6 @@
128129
"convert_project_type",
129130
# Teams Section
130131
"get_team_metadata",
131-
"invite_contributor_to_team",
132132
"search_team_contributors",
133133
# Projects Section
134134
"create_project_from_metadata",
@@ -199,6 +199,8 @@
199199
"consensus",
200200
"upload_video_to_project",
201201
"upload_images_to_project",
202+
"add_contributors_to_project",
203+
"invite_contributors_to_team",
202204
]
203205

204206
__author__ = "Superannotate"

src/superannotate/lib/app/analytics/aggregators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import copy
22
import json
33
import logging
4-
from dataclasses import dataclass
54
from pathlib import Path
65
from typing import List
76
from typing import Optional
87
from typing import Union
98

109
import lib.core as constances
1110
import pandas as pd
11+
from dataclasses import dataclass
1212
from lib.app.exceptions import AppException
1313
from lib.core import ATTACHED_VIDEO_ANNOTATION_POSTFIX
1414
from lib.core import PIXEL_ANNOTATION_POSTFIX

src/superannotate/lib/app/annotation_helpers.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""SuperAnnotate format annotation JSON helpers"""
2+
import datetime
23
import json
34

45
from superannotate.lib.app.exceptions import AppException
@@ -33,6 +34,18 @@ def _postprocess_annotation_json(annotation_json, path):
3334
return annotation_json
3435

3536

37+
def _add_created_updated(annotation):
38+
created_at = (
39+
datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[
40+
:-3
41+
]
42+
+ "Z"
43+
)
44+
annotation["createdAt"] = created_at
45+
annotation["updatedAt"] = created_at
46+
return annotation
47+
48+
3649
def add_annotation_comment_to_json(
3750
annotation_json,
3851
comment_text,
@@ -63,13 +76,17 @@ def add_annotation_comment_to_json(
6376
annotation_json, image_name=image_name
6477
)
6578

79+
user_action = {"email": comment_author, "role": "Admin"}
80+
6681
annotation = {
67-
"type": "comment",
6882
"x": comment_coords[0],
6983
"y": comment_coords[1],
7084
"correspondence": [{"text": comment_text, "email": comment_author}],
7185
"resolved": resolved,
86+
"createdBy": user_action,
87+
"updatedBy": user_action,
7288
}
89+
annotation = _add_created_updated(annotation)
7390
annotation_json["comments"].append(annotation)
7491

7592
return _postprocess_annotation_json(annotation_json, path)
@@ -118,6 +135,7 @@ def add_annotation_bbox_to_json(
118135
else annotation_class_attributes,
119136
}
120137

138+
annotation = _add_created_updated(annotation)
121139
annotation_json["instances"].append(annotation)
122140

123141
return _postprocess_annotation_json(annotation_json, path)
@@ -127,6 +145,7 @@ def add_annotation_point_to_json(
127145
annotation_json,
128146
point,
129147
annotation_class_name,
148+
image_name,
130149
annotation_class_attributes=None,
131150
error=None,
132151
):
@@ -148,7 +167,7 @@ def add_annotation_point_to_json(
148167
if len(point) != 2:
149168
raise AppException("Point should be 2 element float list.")
150169

151-
annotation_json, path = _preprocess_annotation_json(annotation_json)
170+
annotation_json, path = _preprocess_annotation_json(annotation_json, image_name)
152171

153172
annotation = {
154173
"type": "point",
@@ -165,6 +184,7 @@ def add_annotation_point_to_json(
165184
else annotation_class_attributes,
166185
}
167186

187+
annotation = _add_created_updated(annotation)
168188
annotation_json["instances"].append(annotation)
169189

170190
return _postprocess_annotation_json(annotation_json, path)

src/superannotate/lib/app/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def get_s3_annotation_paths(folder_path, s3_bucket, annotation_paths, recursive)
8787

8888
paginator = s3_client.get_paginator("list_objects_v2")
8989
for data in paginator.paginate(Bucket=s3_bucket, Prefix=folder_path):
90-
for annotation in data["Contents"]:
90+
for annotation in data.get("Contents", []):
9191
key = annotation["Key"]
9292
if (
9393
key.endswith(VECTOR_ANNOTATION_POSTFIX)

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def export_project(
144144
sys.exit(0)
145145

146146
def upload_preannotations(
147-
self, project, folder, data_set_name=None, task=None, format=None
147+
self, project, folder, dataset_name=None, task=None, format=None
148148
):
149149
"""
150150
To upload preannotations from folder to project use
@@ -153,20 +153,19 @@ def upload_preannotations(
153153
Only when COCO format is specified dataset-name and task arguments are required.
154154
dataset-name specifies JSON filename (without extension) in <folder_path>.
155155
task specifies the COCO task for conversion. Please see import_annotation_format for more details.
156-
The annotation classes will be created during the execution of this command.
157156
"""
158157
self._upload_annotations(
159158
project=project,
160159
folder=folder,
161160
format=format,
162-
data_set_name=data_set_name,
161+
dataset_name=dataset_name,
163162
task=task,
164163
pre=True,
165164
)
166165
sys.exit(0)
167166

168167
def upload_annotations(
169-
self, project, folder, data_set_name=None, task=None, format=None
168+
self, project, folder, dataset_name=None, task=None, format=None
170169
):
171170
"""
172171
To upload annotations from folder to project use
@@ -175,29 +174,28 @@ def upload_annotations(
175174
Only when COCO format is specified dataset-name and task arguments are required.
176175
dataset-name specifies JSON filename (without extension) in <folder_path>.
177176
task specifies the COCO task for conversion. Please see import_annotation_format for more details.
178-
The annotation classes will be created during the execution of this command.
179177
"""
180178
self._upload_annotations(
181179
project=project,
182180
folder=folder,
183181
format=format,
184-
data_set_name=data_set_name,
182+
dataset_name=dataset_name,
185183
task=task,
186184
pre=False,
187185
)
188186
sys.exit(0)
189187

190188
def _upload_annotations(
191-
self, project, folder, format, data_set_name, task, pre=True
189+
self, project, folder, format, dataset_name, task, pre=True
192190
):
193191
project_name, folder_name = split_project_path(project)
194192
project = self.controller.get_project_metadata(project_name=project_name).data
195193
if not format:
196194
format = "SuperAnnotate"
197-
if not data_set_name and format == "COCO":
195+
if not dataset_name and format == "COCO":
198196
raise Exception("Data-set name is required")
199-
elif not data_set_name:
200-
data_set_name = ""
197+
elif not dataset_name:
198+
dataset_name = ""
201199
if not task:
202200
task = "object_detection"
203201
annotations_path = folder
@@ -207,18 +205,13 @@ def _upload_annotations(
207205
input_dir=folder,
208206
output_dir=temp_dir,
209207
dataset_format=format,
210-
dataset_name=data_set_name,
208+
dataset_name=dataset_name,
211209
project_type=constances.ProjectType.get_name(
212210
project["project"].project_type
213211
),
214212
task=task,
215213
)
216214
annotations_path = temp_dir
217-
classes_path = f"{annotations_path}/classes/classes.json"
218-
self.controller.create_annotation_classes(
219-
project_name=project_name,
220-
annotation_classes=json.load(open(classes_path)),
221-
)
222215
if pre:
223216
upload_preannotations_from_folder_to_project(
224217
project_name, annotations_path

0 commit comments

Comments
 (0)