Skip to content

Commit f31505d

Browse files
authored
Merge pull request #444 from superannotateai/session_fix
Session fix
2 parents 3e025f2 + 525f251 commit f31505d

File tree

17 files changed

+128
-200
lines changed

17 files changed

+128
-200
lines changed

src/superannotate/__init__.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@
22
import sys
33

44
sys.path.append(os.path.split(os.path.realpath(__file__))[0])
5-
from superannotate.lib.app.input_converters.conversion import (
6-
convert_json_version,
7-
) # noqa
8-
from superannotate.lib.app.input_converters.conversion import (
9-
convert_project_type,
10-
) # noqa
11-
125

136
import logging.config # noqa
147
import requests # noqa
158
from packaging.version import parse # noqa
9+
from superannotate.lib.app.input_converters import convert_json_version # noqa
10+
from superannotate.lib.app.input_converters import convert_project_type # noqa
1611
from superannotate.lib.app.analytics.class_analytics import class_distribution # noqa
1712
from superannotate.lib.app.exceptions import AppException # noqa
18-
from superannotate.lib.app.input_converters import convert_json_version
13+
from superannotate.lib.app.input_converters import convert_json_version # noqa
1914
from superannotate.lib.app.input_converters import convert_project_type # noqa
2015
from superannotate.lib.app.input_converters import export_annotation # noqa
2116
from superannotate.lib.app.input_converters import import_annotation # noqa
@@ -26,7 +21,6 @@
2621
from superannotate.logger import get_default_logger # noqa
2722
from superannotate.version import __version__ # noqa
2823

29-
3024
SESSIONS = {}
3125

3226
__all__ = [

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

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

98
import lib.core as constances
109
import pandas as pd
10+
from dataclasses import dataclass
1111
from lib.app.exceptions import AppException
1212
from lib.core import ATTACHED_VIDEO_ANNOTATION_POSTFIX
1313
from lib.core import PIXEL_ANNOTATION_POSTFIX

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import functools
22
import os
33
import sys
4-
from abc import abstractmethod
54
from inspect import signature
65
from pathlib import Path
76
from types import FunctionType
@@ -11,8 +10,8 @@
1110
import lib.core as constants
1211
from lib.app.helpers import extract_project_folder
1312
from lib.app.interface.types import validate_arguments
13+
from lib.core import CONFIG
1414
from lib.core.exceptions import AppException
15-
from lib.core.reporter import Session
1615
from lib.infrastructure.controller import Controller
1716
from lib.infrastructure.repositories import ConfigRepository
1817
from mixpanel import Mixpanel
@@ -27,15 +26,14 @@ def __init__(
2726
token: str = None,
2827
config_path: str = constants.CONFIG_PATH,
2928
):
30-
host = constants.BACKEND_URL
3129
env_token = os.environ.get("SA_TOKEN")
30+
host = os.environ.get("SA_URL", constants.BACKEND_URL)
3231
version = os.environ.get("SA_VERSION", "v1")
3332
ssl_verify = bool(os.environ.get("SA_SSL", True))
3433
if token:
3534
token = Controller.validate_token(token=token)
3635
elif env_token:
3736
host = os.environ.get("SA_URL", constants.BACKEND_URL)
38-
3937
token = Controller.validate_token(env_token)
4038
else:
4139
config_path = os.path.expanduser(str(config_path))
@@ -68,7 +66,6 @@ def token(self):
6866
return self._token
6967

7068

71-
7269
class Tracker:
7370
def get_mp_instance(self) -> Mixpanel:
7471
if self.client:
@@ -149,7 +146,7 @@ def _track_method(self, args, kwargs, success: bool):
149146
self._track(
150147
user_id,
151148
event_name,
152-
{**default, **properties, **Session.get_current_session().data},
149+
{**default, **properties, **CONFIG.get_current_session().data},
153150
)
154151

155152
def __get__(self, obj, owner=None):

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
logger = get_default_logger()
6262

6363

64-
6564
class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
6665
def get_team_metadata(self):
6766
"""Returns team metadata
@@ -313,7 +312,6 @@ def rename_project(self, project: NotEmptyStr, new_name: NotEmptyStr):
313312
)
314313
return ProjectSerializer(response.data).serialize()
315314

316-
317315
def get_folder_metadata(self, project: NotEmptyStr, folder_name: NotEmptyStr):
318316
"""Returns folder metadata
319317
@@ -687,9 +685,7 @@ def assign_items(
687685

688686
project_name, folder_name = extract_project_folder(project)
689687

690-
response = self.controller.assign_items(
691-
project, folder_name, item_names, user
692-
)
688+
response = self.controller.assign_items(project, folder_name, item_names, user)
693689

694690
if not response.errors:
695691
logger.info(f"Assign items to user {user}")
@@ -733,8 +729,8 @@ def assign_images(
733729

734730
warning_msg = (
735731
"We're deprecating the assign_images function. Please use assign_items instead."
736-
"Learn more. \n"
737-
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.assign_items"
732+
"Learn more. \n"
733+
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.assign_items"
738734
)
739735
logger.warning(warning_msg)
740736
warnings.warn(warning_msg, DeprecationWarning)
@@ -788,8 +784,8 @@ def unassign_images(
788784

789785
warning_msg = (
790786
"We're deprecating the unassign_images function. Please use unassign_items instead."
791-
"Learn more. \n"
792-
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.unassign_items"
787+
"Learn more. \n"
788+
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.unassign_items"
793789
)
794790
logger.warning(warning_msg)
795791
warnings.warn(warning_msg, DeprecationWarning)

src/superannotate/lib/core/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from os.path import expanduser
2-
from pathlib import Path
32

3+
from superannotate.lib.core.config import Config
44
from superannotate.lib.core.enums import AnnotationStatus
55
from superannotate.lib.core.enums import ImageQuality
66
from superannotate.lib.core.enums import ProjectState
@@ -13,6 +13,9 @@
1313
from superannotate.lib.core.enums import UserRole
1414

1515

16+
CONFIG = Config()
17+
18+
1619
CONFIG_PATH = "~/.superannotate/config.json"
1720
CONFIG_FILE_LOCATION = expanduser(CONFIG_PATH)
1821
LOG_FILE_LOCATION = expanduser("~/.superannotate/sa.log")
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import threading
2+
from typing import Dict
3+
4+
from dataclasses import dataclass
5+
from dataclasses import field
6+
7+
8+
class Session:
9+
def __init__(self):
10+
self.pk = threading.get_ident()
11+
self._data_dict = {}
12+
13+
def __enter__(self):
14+
return self
15+
16+
def __exit__(self, type, value, traceback):
17+
if type is not None:
18+
return False
19+
20+
def __del__(self):
21+
Config().delete_current_session()
22+
23+
@property
24+
def data(self):
25+
return self._data_dict
26+
27+
@staticmethod
28+
def get_current_session():
29+
return Config().get_current_session()
30+
31+
def __setitem__(self, key, item):
32+
self._data_dict[key] = item
33+
34+
def __getitem__(self, key):
35+
return self._data_dict[key]
36+
37+
def __repr__(self):
38+
return repr(self._data_dict)
39+
40+
def clear(self):
41+
return self._data_dict.clear()
42+
43+
44+
class Singleton(type):
45+
_instances = {}
46+
_lock = threading.Lock()
47+
48+
def __call__(cls, *args, **kwargs):
49+
if cls not in cls._instances:
50+
with cls._lock:
51+
if cls not in cls._instances:
52+
cls._instances[cls] = super().__call__(*args, **kwargs)
53+
return cls._instances[cls]
54+
55+
56+
@dataclass()
57+
class Config(metaclass=Singleton):
58+
SESSIONS: Dict[int, Session] = field(default_factory=dict)
59+
60+
def get_current_session(self):
61+
session = self.SESSIONS.get(threading.get_ident())
62+
if not session:
63+
session = Session()
64+
self.SESSIONS.update({session.pk: session})
65+
return session
66+
67+
def delete_current_session(self):
68+
ident = threading.get_ident()
69+
if ident in self.SESSIONS:
70+
del self.SESSIONS[ident]

src/superannotate/lib/core/reporter.py

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Union
77

88
import tqdm
9+
from lib.core import CONFIG
910
from superannotate.logger import get_default_logger
1011

1112

@@ -31,59 +32,13 @@ def init_spin(self):
3132
sys.stdout.write("\b")
3233

3334

34-
class Session:
35-
def __init__(self):
36-
self.pk = threading.get_ident()
37-
self._data_dict = {}
38-
39-
def __enter__(self):
40-
return self
41-
42-
def __exit__(self, type, value, traceback):
43-
if type is not None:
44-
return False
45-
46-
def __del__(self):
47-
globs = globals()
48-
# if "SESSIONS" in globs and globs.get("SESSIONS", {}).get(self.pk):
49-
# del globs["SESSIONS"][self.pk]
50-
51-
@property
52-
def data(self):
53-
return self._data_dict
54-
55-
@staticmethod
56-
def get_current_session():
57-
globs = globals()
58-
if not globs.get("SESSIONS") or not globs["SESSIONS"].get(
59-
threading.get_ident()
60-
):
61-
session = Session()
62-
globals().update({"SESSIONS": {session.pk: session}})
63-
return session
64-
return globs["SESSIONS"][threading.get_ident()]
65-
66-
def __setitem__(self, key, item):
67-
self._data_dict[key] = item
68-
69-
def __getitem__(self, key):
70-
return self._data_dict[key]
71-
72-
def __repr__(self):
73-
return repr(self._data_dict)
74-
75-
def clear(self):
76-
return self._data_dict.clear()
77-
78-
7935
class Reporter:
8036
def __init__(
8137
self,
8238
log_info: bool = True,
8339
log_warning: bool = True,
8440
disable_progress_bar: bool = False,
8541
log_debug: bool = True,
86-
session: Session = None,
8742
):
8843
self.logger = get_default_logger()
8944
self._log_info = log_info
@@ -95,7 +50,7 @@ def __init__(
9550
self.debug_messages = []
9651
self.custom_messages = defaultdict(set)
9752
self.progress_bar = None
98-
self.session = session
53+
self.session = CONFIG.get_current_session()
9954
self._spinner = None
10055

10156
def start_spinner(self):

src/superannotate/lib/core/response.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def __init__(self, status: str = None, data: Union[dict, list] = None):
1010

1111
def __str__(self):
1212
return f"Response object with status:{self.status}, data : {self.data}, errors: {self.errors} "
13+
1314
@property
1415
def data(self):
1516
return self._data

src/superannotate/lib/core/serviceproviders.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ def un_assign_items(
218218
project_id: int,
219219
folder_name: str,
220220
item_names: list,
221-
222221
):
223222
raise NotImplementedError
224223

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,9 @@ def execute(self):
816816
if self.is_valid():
817817
export_path = str(
818818
self.destination
819-
/ Path(f"{self._project.name} {datetime.now().strftime('%B %d %Y %H_%M')}")
819+
/ Path(
820+
f"{self._project.name} {datetime.now().strftime('%B %d %Y %H_%M')}"
821+
)
820822
)
821823
self.reporter.log_info(
822824
f"Downloading the annotations of the requested items to {export_path}\nThis might take a while…"

0 commit comments

Comments
 (0)