Skip to content

Commit 95f169a

Browse files
authored
Merge pull request #382 from superannotateai/friday
Friday
2 parents af038c0 + e8eee43 commit 95f169a

File tree

79 files changed

+5002
-1109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+5002
-1109
lines changed

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=loads cope
5+
addopts = -n auto --dist=loadscope

src/superannotate/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import requests
66
import superannotate.lib.core as constances
77
from packaging.version import parse
8+
from superannotate.lib import get_default_controller
89
from superannotate.lib.app.analytics.class_analytics import class_distribution
910
from superannotate.lib.app.exceptions import AppException
1011
from superannotate.lib.app.input_converters.conversion import convert_json_version
@@ -28,7 +29,6 @@
2829
from superannotate.lib.app.interface.sdk_interface import benchmark
2930
from superannotate.lib.app.interface.sdk_interface import clone_project
3031
from superannotate.lib.app.interface.sdk_interface import consensus
31-
from superannotate.lib.app.interface.sdk_interface import controller
3232
from superannotate.lib.app.interface.sdk_interface import copy_image
3333
from superannotate.lib.app.interface.sdk_interface import copy_images
3434
from superannotate.lib.app.interface.sdk_interface import create_annotation_class
@@ -109,9 +109,13 @@
109109
from superannotate.logger import get_default_logger
110110
from superannotate.version import __version__
111111

112+
113+
controller = get_default_controller()
114+
112115
__all__ = [
113116
"__version__",
114117
"controller",
118+
"constances",
115119
# Utils
116120
"AppException",
117121
"validate_annotations",
@@ -235,4 +239,5 @@ def log_version_info():
235239
)
236240

237241

238-
log_version_info()
242+
if not os.environ.get("SA_VERSION_CHECK", "True").lower() == "false":
243+
log_version_info()

src/superannotate/lib/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
import os
22
import sys
33

4+
5+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
46
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7+
8+
controller = None
9+
10+
11+
def get_default_controller():
12+
from lib.infrastructure.controller import Controller
13+
14+
global controller
15+
controller = Controller()
16+
return controller

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def __init__(self):
1010
def controller(self):
1111
if not ConfigRepository().get_one("token"):
1212
raise Exception("Config does not exists!")
13-
controller = Controller.get_instance()
13+
controller = Controller()
1414
if self._config_path:
15-
controller.init(self._config_path)
15+
controller.init(config_path=self._config_path)
1616
return controller

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,16 @@
1212
from lib.app.interface.sdk_interface import attach_document_urls_to_project
1313
from lib.app.interface.sdk_interface import attach_image_urls_to_project
1414
from lib.app.interface.sdk_interface import attach_video_urls_to_project
15+
from lib.app.interface.sdk_interface import controller
1516
from lib.app.interface.sdk_interface import create_folder
1617
from lib.app.interface.sdk_interface import create_project
1718
from lib.app.interface.sdk_interface import upload_annotations_from_folder_to_project
1819
from lib.app.interface.sdk_interface import upload_images_from_folder_to_project
1920
from lib.app.interface.sdk_interface import upload_preannotations_from_folder_to_project
2021
from lib.app.interface.sdk_interface import upload_videos_from_folder_to_project
2122
from lib.core.entities import ConfigEntity
22-
from lib.infrastructure.controller import Controller
2323
from lib.infrastructure.repositories import ConfigRepository
2424

25-
controller = Controller.get_instance()
26-
2725

2826
class CLIFacade(BaseInterfaceFacade):
2927
"""

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

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import boto3
1414
import lib.core as constances
15+
from lib import controller
1516
from lib.app.annotation_helpers import add_annotation_bbox_to_json
1617
from lib.app.annotation_helpers import add_annotation_comment_to_json
1718
from lib.app.annotation_helpers import add_annotation_point_to_json
@@ -21,6 +22,7 @@
2122
from lib.app.interface.types import AnnotationStatuses
2223
from lib.app.interface.types import AnnotationType
2324
from lib.app.interface.types import AnnotatorRole
25+
from lib.app.interface.types import ClassType
2426
from lib.app.interface.types import EmailStr
2527
from lib.app.interface.types import ImageQualityChoices
2628
from lib.app.interface.types import NotEmptyStr
@@ -33,35 +35,37 @@
3335
from lib.app.serializers import SettingsSerializer
3436
from lib.app.serializers import TeamSerializer
3537
from lib.core import LIMITED_FUNCTIONS
38+
from lib.core.entities.project_entities import AnnotationClassEntity
3639
from lib.core.enums import ImageQuality
3740
from lib.core.exceptions import AppException
3841
from lib.core.types import AttributeGroup
39-
from lib.core.types import ClassesJson
4042
from lib.core.types import MLModel
4143
from lib.core.types import Project
42-
from lib.infrastructure.controller import Controller
4344
from pydantic import conlist
4445
from pydantic import parse_obj_as
4546
from pydantic import StrictBool
4647
from superannotate.logger import get_default_logger
4748
from tqdm import tqdm
4849

49-
controller = Controller.get_instance()
50+
5051
logger = get_default_logger()
5152

5253

5354
@validate_arguments
54-
def init(path_to_config_json: Optional[str] = None):
55+
def init(path_to_config_json: Optional[str] = None, token: str = None):
5556
"""
5657
Initializes and authenticates to SuperAnnotate platform using the config file.
5758
If not initialized then $HOME/.superannotate/config.json
5859
will be used.
5960
6061
:param path_to_config_json: Location to config JSON file
6162
:type path_to_config_json: str or Path
63+
64+
:param token: Team token
65+
:type token: str
6266
"""
6367
global controller
64-
controller.init(path_to_config_json)
68+
controller.init(config_path=path_to_config_json, token=token)
6569

6670

6771
@validate_arguments
@@ -1525,6 +1529,7 @@ def create_annotation_class(
15251529
name: NotEmptyStr,
15261530
color: NotEmptyStr,
15271531
attribute_groups: Optional[List[AttributeGroup]] = None,
1532+
type: ClassType = "object",
15281533
):
15291534
"""Create annotation class in project
15301535
@@ -1538,19 +1543,25 @@ def create_annotation_class(
15381543
[ { "name": "tall", "is_multiselect": 0, "attributes": [ { "name": "yes" }, { "name": "no" } ] },
15391544
{ "name": "age", "is_multiselect": 0, "attributes": [ { "name": "young" }, { "name": "old" } ] } ]
15401545
:type attribute_groups: list of dicts
1546+
:param type: class type
1547+
:type type: str
15411548
15421549
:return: new class metadata
15431550
:rtype: dict
15441551
"""
15451552
if isinstance(project, Project):
15461553
project = project.dict()
15471554
attribute_groups = (
1548-
list(map(lambda x: x.dict(), attribute_groups)) if attribute_groups else None
1555+
list(map(lambda x: x.dict(), attribute_groups)) if attribute_groups else []
15491556
)
15501557
response = controller.create_annotation_class(
1551-
project_name=project, name=name, color=color, attribute_groups=attribute_groups
1558+
project_name=project,
1559+
name=name,
1560+
color=color,
1561+
attribute_groups=attribute_groups,
1562+
class_type=type,
15521563
)
1553-
return response.data.to_dict()
1564+
return response.data.dict()
15541565

15551566

15561567
@Trackable
@@ -1595,7 +1606,7 @@ def download_annotation_classes_json(project: NotEmptyStr, folder: Union[str, Pa
15951606
@validate_arguments
15961607
def create_annotation_classes_from_classes_json(
15971608
project: Union[NotEmptyStr, dict],
1598-
classes_json: Union[List[ClassesJson], str, Path],
1609+
classes_json: Union[List[AnnotationClassEntity], str, Path],
15991610
from_s3_bucket=False,
16001611
):
16011612
"""Creates annotation classes in project from a SuperAnnotate format
@@ -1611,33 +1622,32 @@ def create_annotation_classes_from_classes_json(
16111622
:return: list of created annotation class metadatas
16121623
:rtype: list of dicts
16131624
"""
1614-
if not isinstance(classes_json, list):
1615-
logger.info(
1616-
"Creating annotation classes in project %s from %s.", project, classes_json,
1617-
)
1625+
classes_json_initial = classes_json
1626+
if isinstance(classes_json, str) or isinstance(classes_json, Path):
16181627
if from_s3_bucket:
16191628
from_session = boto3.Session()
16201629
from_s3 = from_session.resource("s3")
16211630
file = io.BytesIO()
16221631
from_s3_object = from_s3.Object(from_s3_bucket, classes_json)
16231632
from_s3_object.download_fileobj(file)
16241633
file.seek(0)
1625-
annotation_classes = parse_obj_as(List[ClassesJson], json.load(file))
1634+
data = file
16261635
else:
1627-
annotation_classes = parse_obj_as(
1628-
List[ClassesJson], json.load(open(classes_json))
1629-
)
1630-
1631-
else:
1632-
annotation_classes = classes_json
1633-
1634-
annotation_classes = list(
1635-
map(lambda annotation_class: annotation_class.dict(), annotation_classes)
1636+
data = open(classes_json)
1637+
classes_json = json.load(data)
1638+
annotation_classes = parse_obj_as(List[AnnotationClassEntity], classes_json)
1639+
logger.info(
1640+
"Creating annotation classes in project %s from %s.",
1641+
project,
1642+
classes_json_initial,
16361643
)
16371644
response = controller.create_annotation_classes(
16381645
project_name=project, annotation_classes=annotation_classes,
16391646
)
1640-
return response.data
1647+
if response.errors:
1648+
raise AppException(response.errors)
1649+
1650+
return [i.dict() for i in response.data]
16411651

16421652

16431653
@Trackable

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Union
33

44
from lib.core.enums import AnnotationStatus
5+
from lib.core.enums import ClassTypeEnum
56
from lib.core.enums import ProjectType
67
from lib.core.enums import UserRole
78
from lib.core.exceptions import AppException
@@ -12,6 +13,7 @@
1213
from pydantic import ValidationError
1314
from pydantic.errors import StrRegexError
1415

16+
1517
NotEmptyStr = constr(strict=True, min_length=1)
1618

1719

@@ -88,6 +90,15 @@ def validate(cls, value: Union[str]) -> Union[str]:
8890
return value
8991

9092

93+
class ClassType(StrictStr):
94+
@classmethod
95+
def validate(cls, value: Union[str]) -> Union[str]:
96+
enum_values = [e.name.lower() for e in ClassTypeEnum]
97+
if value.lower() not in enum_values:
98+
raise TypeError(f"Available class_types are {', '.join(enum_values)}. ")
99+
return value.lower()
100+
101+
91102
class AnnotationStatuses(StrictStr):
92103
@classmethod
93104
def validate(cls, value: Union[str]) -> Union[str]:

src/superannotate/lib/app/mixp/decorators.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import functools
22
import sys
33

4-
from lib.infrastructure.controller import Controller
4+
from lib import get_default_controller
55
from mixpanel import Mixpanel
66
from superannotate.logger import get_default_logger
77
from version import __version__
88

99
from .utils import parsers
1010

11-
controller = Controller.get_instance()
11+
controller = get_default_controller()
12+
1213

1314
# TODO:
1415
try:

src/superannotate/lib/app/mixp/utils/parsers.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import lib.core as constances
2+
from lib import get_default_controller
23
from lib.app.helpers import extract_project_folder
34
from lib.core.enums import ProjectType
4-
from lib.infrastructure.controller import Controller
55

6-
controller = Controller.get_instance()
6+
controller = get_default_controller()
77

88

99
def get_project_name(project):
@@ -32,7 +32,10 @@ def invite_contributors_to_team(*args, **kwargs):
3232
admin_value = admin[0]
3333
else:
3434
admin_value = admin
35-
return {"event_name": "invite_contributors_to_team", "properties": {"Admin": admin_value}}
35+
return {
36+
"event_name": "invite_contributors_to_team",
37+
"properties": {"Admin": admin_value},
38+
}
3639

3740

3841
def search_team_contributors(*args, **kwargs):
@@ -1079,11 +1082,7 @@ def aggregate_annotations_as_df(*args, **kwargs):
10791082

10801083
return {
10811084
"event_name": "aggregate_annotations_as_df",
1082-
"properties": {
1083-
"Folder Count": len(folder_names),
1084-
"Project Type": project_type
1085-
1086-
},
1085+
"properties": {"Folder Count": len(folder_names), "Project Type": project_type},
10871086
}
10881087

10891088

src/superannotate/lib/app/serializers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from abc import ABC
22

33
import superannotate.lib.core as constance
4+
from pydantic import BaseModel
45
from superannotate.lib.core.entities import BaseEntity
56
from superannotate.lib.core.entities import ImageEntity
67
from superannotate.lib.core.entities import ProjectEntity
@@ -13,6 +14,8 @@ def __init__(self, entity: BaseEntity):
1314
def serialize(self):
1415
if isinstance(self._entity, dict):
1516
return self._entity
17+
if isinstance(self._entity, BaseModel):
18+
return self._entity.dict()
1619
return self._entity.to_dict()
1720

1821

0 commit comments

Comments
 (0)