Skip to content

Commit 9f9d7f5

Browse files
committed
Fix
1 parent 5550937 commit 9f9d7f5

File tree

7 files changed

+181
-94
lines changed

7 files changed

+181
-94
lines changed

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pydicom>=2.0.0
22
boto3>=1.14.53
33
requests==2.26.0
44
requests-toolbelt>=0.9.1
5-
tqdm==4.48.2
5+
tqdm==4.64.0
66
pillow>=7.2.0
77
matplotlib>=3.3.1
88
xmltodict==0.12.0

src/superannotate/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import sys
33

4-
__version__ = "4.4.2dev9"
4+
__version__ = "4.4.2dev10"
55

66
sys.path.append(os.path.split(os.path.realpath(__file__))[0])
77

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import json
66
import os
77
import platform
8+
import re
89
import sys
910
import time
1011
from dataclasses import dataclass
@@ -292,7 +293,6 @@ def _upload_mask(self, item: AnnotationToUpload):
292293
)
293294

294295
async def _upload_small_annotations(self, chunk) -> Report:
295-
self.reporter.update_progress(len(chunk))
296296
failed_annotations, missing_classes, missing_attr_groups, missing_attrs = (
297297
[],
298298
[],
@@ -305,6 +305,7 @@ async def _upload_small_annotations(self, chunk) -> Report:
305305
folder_id=self._folder.id,
306306
items_name_file_map={i.name: i.data for i in chunk},
307307
)
308+
self.reporter.update_progress(len(chunk))
308309
if response.ok:
309310
if response.data.failed_items: # noqa
310311
failed_annotations = response.data.failed_items
@@ -357,7 +358,6 @@ async def upload(_chunk):
357358

358359
async def _upload_big_annotation(self, item) -> Tuple[str, bool]:
359360
try:
360-
self.reporter.update_progress()
361361
is_uploaded = await self._backend_service.upload_big_annotation(
362362
team_id=self._project.team_id,
363363
project_id=self._project.id,
@@ -366,6 +366,7 @@ async def _upload_big_annotation(self, item) -> Tuple[str, bool]:
366366
data=item.data,
367367
chunk_size=5 * 1024 * 1024,
368368
)
369+
self.reporter.update_progress()
369370
if is_uploaded and (
370371
self._project.type == constants.ProjectType.PIXEL.value and item.mask
371372
):
@@ -994,11 +995,18 @@ def get_postfix(self):
994995
return ".json"
995996

996997
def download_annotation_classes(self, path: str):
997-
classes = self._classes.get_all()
998-
classes_path = Path(path) / "classes"
999-
classes_path.mkdir(parents=True, exist_ok=True)
1000-
with open(classes_path / "classes.json", "w+") as file:
1001-
json.dump([i.dict() for i in classes], file, indent=4)
998+
response = self._backend_client.list_annotation_classes(
999+
team_id=self._project.team_id, project_id=self._project.id
1000+
)
1001+
if response.ok:
1002+
classes_path = Path(path) / "classes"
1003+
classes_path.mkdir(parents=True, exist_ok=True)
1004+
with open(classes_path / "classes.json", "w+") as file:
1005+
json.dump(
1006+
[i.dict(exclude_unset=True) for i in response.data], file, indent=4
1007+
)
1008+
else:
1009+
self._response.errors = AppException("Cant download classes.")
10021010

10031011
@staticmethod
10041012
def get_items_count(path: str):
@@ -1084,6 +1092,9 @@ def execute(self):
10841092
class ValidateAnnotationUseCase(BaseReportableUseCase):
10851093
DEFAULT_VERSION = "V1.00"
10861094
SCHEMAS: Dict[str, Draft7Validator] = {}
1095+
PATTERN_MAP = {
1096+
"\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d(?:\\.\\d{3})Z": "YYYY-MM-DDTHH:MM:SS.fffZ"
1097+
}
10871098

10881099
def __init__(
10891100
self,
@@ -1161,6 +1172,13 @@ def oneOf(validator, oneOf, instance, schema): # noqa
11611172
if const_key:
11621173
yield ValidationError(f"invalid {'.'.join(const_key)}")
11631174

1175+
@staticmethod
1176+
def _pattern(validator, patrn, instance, schema):
1177+
if validator.is_type(instance, "string") and not re.search(patrn, instance):
1178+
yield ValidationError(
1179+
f"{instance} does not match {ValidateAnnotationUseCase.PATTERN_MAP.get(patrn, patrn)}"
1180+
)
1181+
11641182
@staticmethod
11651183
def iter_errors(self, instance, _schema=None):
11661184
if _schema is None:
@@ -1241,6 +1259,7 @@ def _get_validator(self, version: str) -> Draft7Validator:
12411259
iter_errors = partial(self.iter_errors, validator)
12421260
validator.iter_errors = iter_errors
12431261
validator.VALIDATORS["oneOf"] = self.oneOf
1262+
validator.VALIDATORS["pattern"] = self._pattern
12441263
ValidateAnnotationUseCase.SCHEMAS[key] = validator
12451264
return validator
12461265

src/superannotate/lib/infrastructure/services.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import io
55
import json
66
import platform
7+
import threading
78
import time
89
from contextlib import contextmanager
10+
from functools import lru_cache
911
from typing import Any
1012
from typing import Callable
1113
from typing import Dict
@@ -31,7 +33,6 @@
3133
from lib.core.service_types import UploadCustomFieldValues
3234
from lib.core.service_types import UserLimits
3335
from lib.core.serviceproviders import SuperannotateServiceProvider
34-
from lib.infrastructure.helpers import timed_lru_cache
3536
from lib.infrastructure.stream_data_handler import StreamedAnnotations
3637
from pydantic import BaseModel
3738
from pydantic import parse_obj_as
@@ -82,23 +83,32 @@ def __init__(
8283
def assets_provider_url(self):
8384
if self.api_url != constance.BACKEND_URL:
8485
# return "http://ec2-18-237-224-179.us-west-2.compute.amazonaws.com:3009/api/v1.01/"
85-
# return "https://sa-assets-provider.us-west-2.elasticbeanstalk.com/api/v1.01/"
86-
return "https://assets-provider.devsuperannotate.com/api/v1.01/"
86+
return (
87+
"https://sa-assets-provider.us-west-2.elasticbeanstalk.com/api/v1.01/"
88+
)
89+
# return "https://assets-provider.devsuperannotate.com/api/v1.01/"
8790
return "https://assets-provider.superannotate.com/api/v1/"
8891

89-
@timed_lru_cache(seconds=360)
90-
def get_session(self):
92+
@lru_cache(maxsize=32)
93+
def _get_session(self, thread_id, ttl=None): # noqa
94+
del ttl
95+
del thread_id
9196
session = requests.Session()
9297
session.headers.update(self.default_headers)
9398
return session
9499

100+
def get_session(self):
101+
return self._get_session(
102+
thread_id=threading.get_ident(), ttl=round(time.time() / 360)
103+
)
104+
95105
@property
96106
def default_headers(self):
97107
return {
98108
"Authorization": self._auth_token,
99109
"authtype": self.AUTH_TYPE,
100110
"Content-Type": "application/json",
101-
"User-Agent": f"Python-SDK-Version: {__version__}; Python: {platform.python_version()}; "
111+
"User-Agent": f"Python-SDK-Version: {__version__}; Python: {platform.python_version()};"
102112
f"OS: {platform.system()}; Team: {self.team_id}",
103113
}
104114

@@ -442,13 +452,12 @@ def attach_files(
442452

443453
def get_folder(self, query_string: str):
444454
get_folder_url = urljoin(self.api_url, self.URL_GET_FOLDER_BY_NAME)
455+
params = {}
445456
if query_string:
446457
query_items = query_string.split("&")
447-
params = {}
448458
for item in query_items:
449459
tmp = item.split("=")
450460
params[tmp[0]] = tmp[1]
451-
452461
response = self._request(get_folder_url, "get", params=params)
453462
if response.ok:
454463
return response.json()
@@ -1141,9 +1150,8 @@ def get_annotations(
11411150
query_params = {
11421151
"team_id": team_id,
11431152
"project_id": project_id,
1153+
"folder_id": folder_id,
11441154
}
1145-
if folder_id:
1146-
query_params["folder_id"] = folder_id
11471155

11481156
handler = StreamedAnnotations(
11491157
self.default_headers,
@@ -1182,9 +1190,8 @@ async def download_annotations(
11821190
query_params = {
11831191
"team_id": team_id,
11841192
"project_id": project_id,
1193+
"folder_id": folder_id,
11851194
}
1186-
if folder_id:
1187-
query_params["folder_id"] = folder_id
11881195
handler = StreamedAnnotations(
11891196
self.default_headers,
11901197
reporter,
@@ -1404,6 +1411,8 @@ async def upload_annotations(
14041411
},
14051412
data=data,
14061413
)
1414+
if not _response.ok:
1415+
raise AppException(_response.json())
14071416
data_json = await _response.json()
14081417
response = ServiceResponse()
14091418
response.status = _response.status

0 commit comments

Comments
 (0)