Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/superannotate/lib/app/interface/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ def get_mp_instance(self) -> Mixpanel:
return Mixpanel(mp_token)

@staticmethod
def get_default_payload(team_name, user_id):
def get_default_payload(team_name, user_email):
return {
"SDK": True,
"Team": team_name,
"Team Owner": user_id,
"User Email": user_email,
"Version": __version__,
"Python version": platform.python_version(),
"Python interpreter type": platform.python_implementation(),
Expand Down Expand Up @@ -207,13 +207,13 @@ def _track_method(self, args, kwargs, success: bool):
function_name = self.function.__name__ if self.function else ""
arguments = self.extract_arguments(self.function, *args, **kwargs)
event_name, properties = self.default_parser(function_name, arguments)
user_id = client.controller.team_data.creator_id
user_email = client.controller.current_user.email
team_name = client.controller.team_data.name

properties["Success"] = success
default = self.get_default_payload(team_name=team_name, user_id=user_id)
default = self.get_default_payload(team_name=team_name, user_email=user_email)
self._track(
user_id,
user_email,
event_name,
{**default, **properties, **CONFIG.get_current_session().data},
)
Expand Down
8 changes: 5 additions & 3 deletions src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,7 @@ def upload_annotations_from_folder_to_project(
response = self.controller.annotations.upload_from_folder(
project=project,
folder=folder,
team=self.controller.team,
user=self.controller.current_user,
annotation_paths=annotation_paths, # noqa: E203
client_s3_bucket=from_s3_bucket,
folder_path=folder_path,
Expand Down Expand Up @@ -1794,7 +1794,7 @@ def upload_image_annotations(
folder=folder,
image=image,
annotations=annotation_json,
team=self.controller.team,
user=self.controller.current_user,
mask=mask,
verbose=verbose,
keep_status=keep_status,
Expand Down Expand Up @@ -2155,7 +2155,9 @@ def add_contributors_to_project(
for email in emails
]
response = self.controller.projects.add_contributors(
team=self.controller.get_team().data, project=project, contributors=contributors
team=self.controller.get_team().data,
project=project,
contributors=contributors,
)
if response.errors:
raise AppException(response.errors)
Expand Down
2 changes: 2 additions & 0 deletions src/superannotate/lib/core/entities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from lib.core.entities.project import ProjectEntity
from lib.core.entities.project import SettingEntity
from lib.core.entities.project import TeamEntity
from lib.core.entities.project import UserEntity
from lib.core.entities.project import WorkflowEntity
from lib.core.entities.project_entities import BaseEntity
from lib.core.entities.project_entities import ImageInfoEntity
Expand Down Expand Up @@ -47,6 +48,7 @@
"S3FileEntity",
"AnnotationClassEntity",
"TeamEntity",
"UserEntity",
"MLModelEntity",
"IntegrationEntity",
]
4 changes: 3 additions & 1 deletion src/superannotate/lib/core/entities/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ class UserEntity(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
email: Optional[str]
picture: Optional[str]
user_role: Optional[int]

class Config:
extra = Extra.ignore


class TeamEntity(BaseModel):
id: Optional[int]
Expand Down
5 changes: 0 additions & 5 deletions src/superannotate/lib/core/repositories.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from abc import ABC
from abc import abstractmethod
from typing import Any
from typing import List
from typing import Optional
Expand All @@ -12,24 +11,20 @@


class BaseReadOnlyRepository(ABC):

def get_one(self, uuid: Union[Condition, int]) -> Optional[Union[BaseModel]]:
raise NotImplementedError


def get_all(self, condition: Optional[Condition] = None) -> List[Union[BaseModel]]:
raise NotImplementedError


class BaseManageableRepository(BaseReadOnlyRepository):

def insert(self, entity: BaseEntity) -> BaseEntity:
raise NotImplementedError

def update(self, entity: BaseEntity) -> BaseEntity:
raise NotImplementedError


def delete(self, uuid: Any):
raise NotImplementedError

Expand Down
4 changes: 4 additions & 0 deletions src/superannotate/lib/core/service_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ class TeamResponse(ServiceResponse):
data: entities.TeamEntity = None


class UserResponse(ServiceResponse):
data: entities.UserEntity = None


class ModelListResponse(ServiceResponse):
data: List[entities.AnnotationClassEntity] = None

Expand Down
5 changes: 5 additions & 0 deletions src/superannotate/lib/core/serviceproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from lib.core.service_types import UploadAnnotationsResponse
from lib.core.service_types import UploadCustomFieldValuesResponse
from lib.core.service_types import UserLimitsResponse
from lib.core.service_types import UserResponse
from lib.core.types import Attachment
from lib.core.types import AttachmentMeta

Expand Down Expand Up @@ -507,6 +508,10 @@ class BaseServiceProvider:
def get_team(self, team_id: int) -> TeamResponse:
raise NotImplementedError

@abstractmethod
def get_user(self, team_id: int) -> UserResponse:
raise NotImplementedError

@abstractmethod
def list_templates(self) -> ServiceResponse:
raise NotImplementedError
Expand Down
14 changes: 7 additions & 7 deletions src/superannotate/lib/core/usecases/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from lib.core.entities import FolderEntity
from lib.core.entities import ImageEntity
from lib.core.entities import ProjectEntity
from lib.core.entities import TeamEntity
from lib.core.entities import UserEntity
from lib.core.exceptions import AppException
from lib.core.reporter import Reporter
from lib.core.response import Response
Expand Down Expand Up @@ -482,7 +482,7 @@ def __init__(
reporter: Reporter,
project: ProjectEntity,
folder: FolderEntity,
team: TeamEntity,
user: UserEntity,
annotation_paths: List[str],
service_provider: BaseServiceProvider,
pre_annotation: bool = False,
Expand All @@ -493,7 +493,7 @@ def __init__(
super().__init__(reporter)
self._project = project
self._folder = folder
self._team = team
self._user = user
self._service_provider = service_provider
self._annotation_classes = service_provider.annotation_classes.list(
Condition("project_id", project.id, EQ)
Expand Down Expand Up @@ -581,7 +581,7 @@ def prepare_annotation(self, annotation: dict, size) -> dict:
raise AppException(errors)

annotation = UploadAnnotationUseCase.set_defaults(
self._team.creator_id, annotation, self._project.type
self._user.email, annotation, self._project.type
)
return annotation

Expand Down Expand Up @@ -827,7 +827,7 @@ def __init__(
project: ProjectEntity,
folder: FolderEntity,
image: ImageEntity,
team: TeamEntity,
user: UserEntity,
service_provider: BaseServiceProvider,
reporter: Reporter,
annotation_upload_data: UploadAnnotationAuthData = None,
Expand All @@ -844,7 +844,7 @@ def __init__(
self._project = project
self._folder = folder
self._image = image
self._team = team
self._user = user
self._service_provider = service_provider
self._annotation_classes = service_provider.annotation_classes.list(
Condition("project_id", project.id, EQ)
Expand Down Expand Up @@ -973,7 +973,7 @@ def execute(self):
annotation_json, mask = self._get_annotation_json()
errors = self._validate_json(annotation_json)
annotation_json = UploadAnnotationUseCase.set_defaults(
self._team.creator_id, annotation_json, self._project.type
self._user.email, annotation_json, self._project.type
)
if not errors:
annotation_file = io.StringIO()
Expand Down
4 changes: 3 additions & 1 deletion src/superannotate/lib/core/usecases/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,9 @@ def execute(self):
failed_images = []
while len(success_images) + len(failed_images) != len(image_ids):
images_metadata = self._service_provider.items.list_by_names(
project=self._project, folder=self._folder, names=self._images_list
project=self._project,
folder=self._folder,
names=self._images_list,
).data

success_images = [
Expand Down
17 changes: 17 additions & 0 deletions src/superannotate/lib/core/usecases/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,23 @@ def execute(self):
return self._response


class GetCurrentUserUseCase(BaseUseCase):
def __init__(self, service_provider: BaseServiceProvider, team_id: int):
super().__init__()
self._service_provider = service_provider
self._team_id = team_id

def execute(self):
response = self._service_provider.get_user(self._team_id)
if not response.ok:
self._response.errors = AppException(
"Unable to retrieve user data. Please verify your credentials."
)
else:
self._response.data = response.data
return self._response


class SearchContributorsUseCase(BaseUseCase):
def __init__(
self,
Expand Down
28 changes: 17 additions & 11 deletions src/superannotate/lib/infrastructure/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from lib.core.entities import ProjectEntity
from lib.core.entities import SettingEntity
from lib.core.entities import TeamEntity
from lib.core.entities import UserEntity
from lib.core.entities.classes import AnnotationClassEntity
from lib.core.entities.integrations import IntegrationEntity
from lib.core.exceptions import AppException
Expand Down Expand Up @@ -583,7 +584,7 @@ def upload_from_folder(
project: ProjectEntity,
folder: FolderEntity,
annotation_paths: List[str],
team: TeamEntity,
user: UserEntity,
keep_status: bool = False,
client_s3_bucket=None,
is_pre_annotations: bool = False,
Expand All @@ -592,7 +593,7 @@ def upload_from_folder(
use_case = usecases.UploadAnnotationsFromFolderUseCase(
project=project,
folder=folder,
team=team,
user=user,
annotation_paths=annotation_paths,
service_provider=self.service_provider,
pre_annotation=is_pre_annotations,
Expand All @@ -608,7 +609,7 @@ def upload_image_annotations(
project: ProjectEntity,
folder: FolderEntity,
image: ImageEntity,
team: TeamEntity,
user: UserEntity,
annotations: dict,
mask: io.BytesIO = None,
verbose: bool = True,
Expand All @@ -617,7 +618,7 @@ def upload_image_annotations(
use_case = usecases.UploadAnnotationUseCase(
project=project,
folder=folder,
team=team,
user=user,
service_provider=self.service_provider,
image=image,
annotations=annotations,
Expand Down Expand Up @@ -795,6 +796,7 @@ def __init__(self, config: ConfigEntity):

self.service_provider = ServiceProvider(http_client)
self._team = self.get_team().data
self._user = self.get_current_user()
self.annotation_classes = AnnotationClassManager(self.service_provider)
self.projects = ProjectManager(self.service_provider)
self.folders = FolderManager(self.service_provider)
Expand All @@ -805,13 +807,9 @@ def __init__(self, config: ConfigEntity):
self.models = ModelManager(self.service_provider)
self.integrations = IntegrationManager(self.service_provider)

@staticmethod
def validate_token(token: str):
try:
int(token.split("=")[-1])
except ValueError:
raise AppException("Invalid token.")
return token
@property
def current_user(self):
return self._user

@property
def user_id(self):
Expand All @@ -828,6 +826,14 @@ def get_team(self):
service_provider=self.service_provider, team_id=self.team_id
).execute()

def get_current_user(self) -> UserEntity:
response = usecases.GetCurrentUserUseCase(
service_provider=self.service_provider, team_id=self.team_id
).execute()
if response.errors:
raise AppException(response.errors)
return response.data

@property
def team_data(self):
if not self._team_data:
Expand Down
1 change: 1 addition & 0 deletions src/superannotate/lib/infrastructure/repositories.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io

from lib.core.entities import S3FileEntity
from lib.core.repositories import BaseS3Repository

Expand Down
7 changes: 7 additions & 0 deletions src/superannotate/lib/infrastructure/serviceprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from lib.core.service_types import TeamResponse
from lib.core.service_types import UploadAnnotationAuthDataResponse
from lib.core.service_types import UserLimitsResponse
from lib.core.service_types import UserResponse
from lib.core.serviceproviders import BaseServiceProvider
from lib.infrastructure.services.annotation import AnnotationService
from lib.infrastructure.services.annotation_class import AnnotationClassService
Expand All @@ -31,6 +32,7 @@ class ServiceProvider(BaseServiceProvider):
URL_GET_TEMPLATES = "templates"
URL_PREPARE_EXPORT = "export"
URL_GET_EXPORTS = "exports"
URL_USER = "user/ME"
URL_USERS = "users"
URL_GET_EXPORT = "export/{}"
URL_GET_MODEL_METRICS = "ml_models/{}/getCurrentMetrics"
Expand Down Expand Up @@ -59,6 +61,11 @@ def get_team(self, team_id: int) -> TeamResponse:
f"{self.URL_TEAM}/{team_id}", "get", content_type=TeamResponse
)

def get_user(self, team_id: int) -> UserResponse:
return self.client.request(
self.URL_USER, "get", params={"team_id": team_id}, content_type=UserResponse
)

def list_templates(self):
return self.client.request(self.URL_GET_TEMPLATES, "get")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_annotation_last_action_and_creation_type(self):
self.assertEqual(instance["creationType"], "Preannotation")
assert (
annotation["metadata"]["lastAction"]["email"]
== sa.controller.team_data.creator_id
== sa.controller.current_user.email
)
self.assertEqual(
type(annotation["metadata"]["lastAction"]["timestamp"]), int
Expand Down
Loading