Skip to content

Commit 09c986c

Browse files
committed
Start export
1 parent f540a92 commit 09c986c

File tree

5 files changed

+115
-16
lines changed

5 files changed

+115
-16
lines changed

superannotate/__main__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,19 @@ def export_project(command_name, args):
316316
)
317317
args = parser.parse_args(args)
318318

319+
parts = args.project.split('/')
320+
if len(parts) == 1:
321+
project, folder = parts[0], None
322+
elif len(parts) == 2:
323+
project, folder = parts
324+
else:
325+
raise SABaseException(
326+
0, "Project should be in format <project>[/<folder>]"
327+
)
319328
export = sa.prepare_export(
320-
args.project, args.annotation_statuses, args.include_fuse
329+
project, [folder],
330+
annotation_statuses=args.annotation_statuses,
331+
include_fuse=args.include_fuse
321332
)
322333
sa.download_export(
323334
args.project, export, args.folder, not args.disable_extract_zip_contents

superannotate/analytics/common.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,12 +304,15 @@ def __get_user_metadata(annotation):
304304
logger.warning(
305305
"No annotations found in project export root %s", project_root
306306
)
307-
type_postfix = "___objects.json" if annotations_paths[0].match(
308-
"*___objects.json"
309-
) else "___pixel.json"
307+
type_postfix = "___objects.json" if len(
308+
list(Path(project_root).rglob("*___objects.json"))
309+
) > 0 else "___pixel.json"
310310
for annotation_path in annotations_paths:
311311
annotation_json = json.load(open(annotation_path))
312-
image_name = annotation_path.name.split(type_postfix)[0]
312+
parts = annotation_path.name.split(type_postfix)
313+
if len(parts) != 2:
314+
continue
315+
image_name = parts[0]
313316
image_metadata = __get_image_metadata(image_name, annotation_json)
314317
annotation_instance_id = 0
315318
if include_comments:

superannotate/db/exports.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
SABaseException, SAExistingExportNameException,
1818
SANonExistingExportNameException
1919
)
20-
from .project_api import get_project_metadata_bare
20+
from .project_api import get_project_and_folder_metadata, get_project_metadata_bare
2121

2222
logger = logging.getLogger("superannotate-python-sdk")
2323

@@ -97,7 +97,11 @@ def _get_export(export):
9797

9898

9999
def prepare_export(
100-
project, annotation_statuses=None, include_fuse=False, only_pinned=False
100+
project,
101+
folder_names=None,
102+
annotation_statuses=None,
103+
include_fuse=False,
104+
only_pinned=False
101105
):
102106
"""Prepare annotations and classes.json for export. Original and fused images for images with
103107
annotations can be included with include_fuse flag.
@@ -133,6 +137,8 @@ def prepare_export(
133137
"coco": 0,
134138
"time": current_time
135139
}
140+
if folder_names is not None:
141+
json_req["folder_names"] = folder_names
136142
params = {'team_id': team_id, 'project_id': project_id}
137143
response = _api.send_request(
138144
req_type='POST', path='/export', params=params, json_req=json_req
@@ -142,9 +148,10 @@ def prepare_export(
142148
response.status_code, "Couldn't create_export." + response.text
143149
)
144150
res = response.json()
151+
folder_str = "" if folder_names is None else ("/" + str(folder_names))
145152
logger.info(
146-
"Prepared export %s for project %s (ID %s).", res['name'],
147-
project["name"], project["id"]
153+
"Prepared export %s for project %s%s (project ID %s).", res['name'],
154+
project["name"], folder_str, project["id"]
148155
)
149156
return res
150157

tests/test_annotation_adding.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def test_add_bbox(tmpdir):
8989
sa.download_export(project, export, tmpdir)
9090

9191
df = sa.aggregate_annotations_as_df(tmpdir)
92+
print(df)
93+
print(image_name)
9294

9395
num = len(df[df["imageName"] == image_name]["instanceId"].dropna().unique())
9496

tests/test_folders.py

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,25 @@ def test_copy_images(tmpdir):
255255
num_images = sa.get_project_image_count(project)
256256
assert num_images == 4
257257

258+
im1 = sa.get_image_metadata(project, "example_image_2.jpg")
259+
assert im1["annotation_status"] == "InProgress"
260+
258261
sa.create_folder(PROJECT_NAME, "folder2")
259262
project2 = PROJECT_NAME + "/folder2"
260263
num_images = sa.get_project_image_count(project2)
261264
assert num_images == 0
262265

263266
sa.copy_images(
264-
project, project2, ["example_image_2.jpg", "example_image_3.jpg"]
267+
project,
268+
project2, ["example_image_2.jpg", "example_image_3.jpg"],
269+
include_annotations=False,
270+
copy_annotation_status=False,
271+
copy_pin=False
265272
)
266273

274+
im1_copied = sa.get_image_metadata(project2, "example_image_2.jpg")
275+
assert im1_copied["annotation_status"] == "NotStarted"
276+
267277
num_images = sa.get_project_image_count(project2)
268278
assert num_images == 2
269279

@@ -364,18 +374,84 @@ def test_copy_images2(tmpdir):
364374
num_images = sa.get_project_image_count(project2)
365375
assert num_images == 0
366376

377+
sa.pin_image(project, "example_image_2.jpg")
378+
379+
im1 = sa.get_image_metadata(project, "example_image_2.jpg")
380+
assert im1["is_pinned"] == 1
381+
assert im1["annotation_status"] == "InProgress"
382+
367383
sa.copy_images(
368-
project,
369-
project2, ["example_image_2.jpg", "example_image_3.jpg"],
370-
include_annotations=False,
371-
copy_annotation_status=False,
372-
copy_pin=False
384+
project, project2, ["example_image_2.jpg", "example_image_3.jpg"]
373385
)
374386

375387
num_images = sa.get_project_image_count(project2)
376388
assert num_images == 2
377389

378390
ann1 = sa.get_image_annotations(project, "example_image_2.jpg")
379391
ann2 = sa.get_image_annotations(project2, "example_image_2.jpg")
392+
assert ann1 == ann2
393+
394+
im1_copied = sa.get_image_metadata(project2, "example_image_2.jpg")
395+
assert im1_copied["is_pinned"] == 1
396+
assert im1_copied["annotation_status"] == "InProgress"
397+
398+
im2_copied = sa.get_image_metadata(project2, "example_image_3.jpg")
399+
assert im2_copied["is_pinned"] == 0
400+
assert im2_copied["annotation_status"] == "InProgress"
401+
402+
403+
def test_folder_export(tmpdir):
404+
PROJECT_NAME = "test folder export"
405+
tmpdir = Path(tmpdir)
406+
407+
projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True)
408+
for pr in projects_found:
409+
sa.delete_project(pr)
410+
411+
project = sa.create_project(PROJECT_NAME, 'test', 'Vector')
412+
sa.create_annotation_classes_from_classes_json(
413+
project, FROM_FOLDER / "classes" / "classes.json"
414+
)
415+
sa.upload_images_from_folder_to_project(
416+
project, FROM_FOLDER, annotation_status="InProgress"
417+
)
418+
sa.create_folder(project, "folder1")
419+
project = PROJECT_NAME + "/folder1"
420+
sa.upload_images_from_folder_to_project(
421+
project, FROM_FOLDER, annotation_status="InProgress"
422+
)
423+
424+
sa.upload_annotations_from_folder_to_project(project, FROM_FOLDER)
425+
num_images = sa.get_project_image_count(project)
426+
assert num_images == 4
427+
428+
sa.create_folder(PROJECT_NAME, "folder2")
429+
project2 = PROJECT_NAME + "/folder2"
430+
num_images = sa.get_project_image_count(project2)
431+
assert num_images == 0
432+
433+
sa.copy_images(
434+
project, project2, ["example_image_2.jpg", "example_image_3.jpg"]
435+
)
436+
437+
export = sa.prepare_export(PROJECT_NAME, ["folder1", "folder2"])
438+
sa.download_export(project, export, tmpdir)
439+
440+
assert len(list((tmpdir / "classes").rglob("*"))) == 1
441+
442+
assert len(list((tmpdir / "folder1").rglob("*"))) == 4
443+
444+
assert len(list((tmpdir / "folder2").rglob("*"))) == 2
445+
446+
assert len(list((tmpdir).glob("*.*"))) == 0
447+
448+
export = sa.prepare_export(PROJECT_NAME)
449+
sa.download_export(project, export, tmpdir)
450+
451+
assert len(list((tmpdir / "classes").rglob("*"))) == 1
452+
453+
assert len(list((tmpdir / "folder1").rglob("*"))) == 4
454+
455+
assert len(list((tmpdir / "folder2").rglob("*"))) == 2
380456

381-
assert ann1 == ann2
457+
assert len(list((tmpdir).glob("*.*"))) == 4

0 commit comments

Comments
 (0)