Skip to content

Commit 61f0a96

Browse files
committed
Init folder structure
1 parent 4145a6b commit 61f0a96

File tree

6 files changed

+129
-56
lines changed

6 files changed

+129
-56
lines changed

superannotate/__init__.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import json
21
import logging
3-
from pathlib import Path
42

53
import packaging.version
64
import requests
@@ -49,9 +47,10 @@ def consensus(*args, **kwargs):
4947
add_annotation_cuboid_to_image, add_annotation_ellipse_to_image,
5048
add_annotation_point_to_image, add_annotation_polygon_to_image,
5149
add_annotation_polyline_to_image, add_annotation_template_to_image,
52-
create_fuse_image, delete_image, download_image, download_image_annotations,
53-
download_image_preannotations, get_image_annotations, get_image_bytes,
54-
get_image_metadata, get_image_preannotations, search_images,
50+
create_folder, create_fuse_image, delete_image, download_image,
51+
download_image_annotations, download_image_preannotations,
52+
get_folder_metadata, get_image_annotations, get_image_bytes,
53+
get_image_metadata, get_image_preannotations, search_folders, search_images,
5554
set_image_annotation_status, upload_image_annotations
5655
)
5756
from .db.project_images import (
@@ -86,15 +85,14 @@ def consensus(*args, **kwargs):
8685
SANonExistingProjectNameException
8786
)
8887
from .input_converters.conversion import (
89-
coco_split_dataset, convert_project_type, export_annotation,
90-
import_annotation, convert_json_version
88+
coco_split_dataset, convert_json_version, convert_project_type,
89+
export_annotation, import_annotation
9190
)
9291
from .ml.ml_funcs import (
9392
delete_model, download_model, plot_model_metrics, run_prediction,
9493
run_segmentation, run_training, stop_model_training
9594
)
9695
from .ml.ml_models import search_models
97-
9896
from .old_to_new_format_convertor import update_json_format
9997
from .version import __version__
10098

superannotate/common.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import os
55
import sys
66
import time
7-
from tqdm import tqdm
87
from pathlib import Path
9-
from enum import IntEnum
8+
109
import numpy as np
1110
from PIL import Image
11+
from tqdm import tqdm
1212

1313
logger = logging.getLogger("superannotate-python-sdk")
1414

@@ -152,9 +152,6 @@ def rename_kwargs(func_name, kwargs, aliases):
152152
kwargs[new] = kwargs.pop(alias)
153153

154154

155-
logger = logging.getLogger('httplogger')
156-
157-
158155
def hex_to_rgb(hex_string):
159156
"""Converts HEX values to RGB values
160157
"""
@@ -298,14 +295,6 @@ def write_to_json(output_path, json_data):
298295
} # Resolution limit
299296

300297

301-
def process_api_response(data):
302-
logger.info("Maintenance operations are being performed")
303-
if 'metadata' not in data:
304-
return data
305-
306-
return data['data']
307-
308-
309298
def tqdm_converter(
310299
total_num, images_converted, images_not_converted, finish_event
311300
):

superannotate/db/images.py

Lines changed: 110 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
add_annotation_polyline_to_json, add_annotation_template_to_json
1818
)
1919
from ..api import API
20-
from ..common import process_api_response
2120
from ..exceptions import SABaseException
2221
from ..parameter_decorators import project_metadata
2322
from .annotation_classes import (
@@ -46,16 +45,43 @@ def _get_project_root_folder_id(project):
4645
if not response.ok:
4746
raise SABaseException(response.status_code, response.text)
4847

49-
response = process_api_response(response.json())
48+
response = response.json()
5049

5150
return response['folder_id']
5251

5352

53+
def create_folder(project, folder_name):
54+
"""Create a new folder in the project.
55+
56+
:param project: project name or metadata of the project to be deleted
57+
:type project: str or dict
58+
:param folder_name: the new folder's name
59+
:type folder_name: str
60+
61+
:return: dict object metadata the new folder
62+
:rtype: dict
63+
"""
64+
if not isinstance(project, dict):
65+
project = get_project_metadata_bare(project)
66+
params = {"team_id": project["team_id"], "project_id": project["id"]}
67+
data = {"name": folder_name}
68+
response = _api.send_request(
69+
req_type='POST', path='/folder', params=params, json_req=data
70+
)
71+
if not response.ok:
72+
raise SABaseException(
73+
response.status_code, "Couldn't create project " + response.text
74+
)
75+
res = response.json()
76+
return res
77+
78+
5479
def search_images(
5580
project,
5681
image_name_prefix=None,
5782
annotation_status=None,
58-
return_metadata=False
83+
return_metadata=False,
84+
folder_name=None
5985
):
6086
"""Search images by name_prefix (case-insensitive) and annotation status
6187
@@ -76,19 +102,24 @@ def search_images(
76102
if not isinstance(project, dict):
77103
project = get_project_metadata_bare(project)
78104
team_id, project_id = project["team_id"], project["id"]
79-
folder_id = _get_project_root_folder_id(project) # maybe changed in future
80105
if annotation_status is not None:
81106
annotation_status = common.annotation_status_str_to_int(
82107
annotation_status
83108
)
84109

110+
if folder_name is not None:
111+
folder = get_folder_metadata(project, folder_name)
112+
folder_id = folder["id"]
113+
else:
114+
folder_id = None
115+
85116
result_list = []
86117
params = {
87118
'team_id': team_id,
88119
'project_id': project_id,
89-
'folder_id': folder_id,
90120
'annotation_status': annotation_status,
91-
'offset': 0
121+
'offset': 0,
122+
'folder_id': folder_id
92123
}
93124
if image_name_prefix is not None:
94125
params['name'] = image_name_prefix
@@ -97,28 +128,32 @@ def search_images(
97128
response = _api.send_request(
98129
req_type='GET', path='/images', params=params
99130
)
100-
if response.ok:
101-
# print(response.json())
102-
response = process_api_response(response.json())
103-
results = response["data"]
104-
total_got += len(results)
105-
for r in results:
106-
if return_metadata:
107-
result_list.append(r)
108-
else:
109-
result_list.append(r["name"])
110-
111-
if response["count"] <= total_got:
112-
break
113-
params["offset"] = total_got
114-
# print(
115-
# "Got to ", len(result_list),
116-
# response.json()["count"], len(new_results), params['offset']
117-
# )
118-
else:
131+
if not response.ok:
119132
raise SABaseException(
120133
response.status_code, "Couldn't search images " + response.text
121134
)
135+
response = response.json()
136+
images = response["images"]
137+
folders = response["folders"]
138+
139+
image_count = images["count"]
140+
folder_count = folders["count"]
141+
142+
results_images = images["data"]
143+
total_got += len(results_images) + len(folders["data"])
144+
for r in results_images:
145+
if return_metadata:
146+
result_list.append(r)
147+
else:
148+
result_list.append(r["name"])
149+
150+
if image_count + folder_count <= total_got:
151+
break
152+
params["offset"] = total_got
153+
# print(
154+
# "Got to ", len(result_list),
155+
# response.json()["count"], len(new_results), params['offset']
156+
# )
122157

123158
if return_metadata:
124159

@@ -133,6 +168,55 @@ def process_result(x):
133168
return result_list
134169

135170

171+
def get_folder_metadata(project, folder_name):
172+
folders = search_folders(project, folder_name, return_metadata=True)
173+
if len(folders) == 0:
174+
raise SABaseException(0, "Folder doesn't exist")
175+
elif len(folders) > 1:
176+
raise SABaseException(0, "Multiple folders with the same name")
177+
else:
178+
return folders[0]
179+
180+
181+
def search_folders(project, folder_name=None, return_metadata=False):
182+
if not isinstance(project, dict):
183+
project = get_project_metadata_bare(project)
184+
team_id, project_id = project["team_id"], project["id"]
185+
result_list = []
186+
params = {'team_id': team_id, 'project_id': project_id, 'offset': 0}
187+
total_got = 0
188+
total_folders = 0
189+
while True:
190+
response = _api.send_request(
191+
req_type='GET', path='/images', params=params
192+
)
193+
if not response.ok:
194+
raise SABaseException(
195+
response.status_code, "Couldn't search images " + response.text
196+
)
197+
response = response.json()
198+
images = response["images"]
199+
folders = response["folders"]
200+
201+
results_folders = folders["data"]
202+
for r in folders["data"]:
203+
if folder_name is not None and r["name"] != folder_name:
204+
continue
205+
if return_metadata:
206+
result_list.append(r)
207+
else:
208+
result_list.append(r["name"])
209+
210+
total_folders += len(results_folders)
211+
if folders["count"] <= total_folders:
212+
break
213+
214+
total_got += len(images["data"]) + len(results_folders)
215+
params["offset"] = total_got
216+
217+
return result_list
218+
219+
136220
@project_metadata
137221
def get_image_metadata(project, image_names, return_dict_on_single_output=True):
138222
"""Returns image metadata
@@ -219,7 +303,7 @@ def set_image_annotation_status(project, image_name, annotation_status):
219303
if not response.ok:
220304
raise SABaseException(response.status_code, response.text)
221305

222-
response = process_api_response(response.json())
306+
response = response.json()
223307

224308
return response
225309

superannotate/db/search_projects.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import logging
22

33
from ..api import API
4-
from ..exceptions import (SABaseException)
5-
from ..common import process_api_response
4+
from ..exceptions import SABaseException
5+
66
logger = logging.getLogger("superannotate-python-sdk")
7+
78
_api = API.get_instance()
89

910

@@ -34,7 +35,7 @@ def search_projects(
3435
req_type='GET', path='/projects', params=params
3536
)
3637
if response.ok:
37-
new_results = process_api_response(response.json())
38+
new_results = response.json()
3839
result_list += new_results["data"]
3940
if new_results["count"] <= len(result_list):
4041
break

superannotate/ml/ml_funcs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ..api import API
1818
from ..common import (
1919
_AVAILABLE_SEGMENTATION_MODELS, model_training_status_int_to_str,
20-
process_api_response, project_type_str_to_int
20+
project_type_str_to_int
2121
)
2222
from ..db.images import get_image_metadata, search_images
2323
from ..exceptions import SABaseException
@@ -449,7 +449,7 @@ def download_model(model, output_dir):
449449
params=params
450450
)
451451
if response.ok:
452-
response = process_api_response(response.json())
452+
response = response.json()
453453
else:
454454
raise SABaseException(0, "Could not get model info ")
455455

superannotate/ml/ml_models.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from ..common import process_api_response
2-
from ..exceptions import SABaseException
1+
import logging
2+
33
from ..api import API
44
from ..common import project_type_int_to_str
5-
import logging
5+
from ..exceptions import SABaseException
66

77
logger = logging.getLogger("superannotate-python-sdk")
8+
89
_api = API.get_instance()
910

1011

@@ -30,7 +31,7 @@ def search_models(
3031

3132
if not response.ok:
3233
raise SABaseException(0, "could not search models")
33-
result = process_api_response(response.json())
34+
result = response.json()
3435

3536
for model in result['data']:
3637
model['type'] = project_type_int_to_str(model['type'])

0 commit comments

Comments
 (0)