Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
1a241c8
initial priority
dshabin Feb 23, 2022
b6b08b3
fix parser
dshabin Feb 23, 2022
10df0dd
add tqdm
dshabin Feb 23, 2022
ce3d1da
Update docs
dshabin Feb 23, 2022
88cb53c
Update ssl
dshabin Feb 23, 2022
52de468
Add clean priority
dshabin Feb 23, 2022
8d2e236
round frames count in VideoFrameGenerator
VaghinakDev Feb 27, 2022
c3c55fd
Merge branch 'develop' into friday
VaghinakDev Feb 28, 2022
7dd2873
refactor upload_priority_scores
VaghinakDev Mar 2, 2022
22e7e7a
Merge pull request #412 from superannotateai/friday-964-priority
VaghinakDev Mar 2, 2022
b444a68
initial priority
dshabin Feb 23, 2022
1d4582c
fix parser
dshabin Feb 23, 2022
64e068b
add tqdm
dshabin Feb 23, 2022
d36ba89
Update docs
dshabin Feb 23, 2022
e0cad32
Update ssl
dshabin Feb 23, 2022
2e82afe
Add clean priority
dshabin Feb 23, 2022
7272af8
refactor upload_priority_scores
VaghinakDev Mar 2, 2022
cf1c78d
tod
VaghinakDev Mar 2, 2022
118727b
Merge branch 'friday' of https://github.com/superannotateai/superanno…
VaghinakDev Mar 2, 2022
ae71d0a
Update version.py
VaghinakDev Mar 2, 2022
fe70a1d
fix convertor
VaghinakDev Mar 2, 2022
4608a68
Merge branch 'friday' of https://github.com/superannotateai/superanno…
VaghinakDev Mar 2, 2022
dfd634f
Change version
VaghinakDev Mar 2, 2022
2750f6d
Minor changes
VaghinakDev Mar 2, 2022
3f4368b
Added integrations
VaghinakDev Mar 3, 2022
79aa3cf
Update version.py
VaghinakDev Mar 4, 2022
29747d0
Adjusted integrations
VaghinakDev Mar 4, 2022
5f6a7b1
Update version.py
VaghinakDev Mar 4, 2022
392148c
Merge pull request #420 from superannotateai/firday-integrations
VaghinakDev Mar 7, 2022
0e723fc
Added ProjectStatus Enum
VaghinakDev Mar 7, 2022
a67247a
Update version.py
VaghinakDev Mar 7, 2022
b1bdbef
Update version.py
VaghinakDev Mar 7, 2022
1089d95
Friday 840
VaghinakDev Mar 7, 2022
3766bc7
Update version.py
VaghinakDev Mar 7, 2022
a4a9d0b
Merge branch 'friday' of https://github.com/superannotateai/superanno…
VaghinakDev Mar 7, 2022
d2b24a0
Update version.py
VaghinakDev Mar 7, 2022
e2220d3
Added tags handeling, tests adjuted
VaghinakDev Mar 10, 2022
6e442bb
Update version.py
VaghinakDev Mar 10, 2022
c7e87b7
Update version.py
VaghinakDev Mar 10, 2022
3afbe3c
Deleted default description valie ...
VaghinakDev Mar 11, 2022
63c6b8a
Update version.py
VaghinakDev Mar 11, 2022
2ad01b5
Udpate scemas version, set project status not started on create
VaghinakDev Mar 15, 2022
b67cb28
Merge branch 'friday' of https://github.com/superannotateai/superanno…
VaghinakDev Mar 15, 2022
b5fbf3d
Update version.py
VaghinakDev Mar 15, 2022
732460b
Update version.py
VaghinakDev Mar 15, 2022
bd26bf5
fix project validations on create annotation classes
VaghinakDev Mar 16, 2022
34df048
Update version.py
VaghinakDev Mar 16, 2022
92876c4
Update version.py
VaghinakDev Mar 16, 2022
b16c207
Update version.py
VaghinakDev Mar 16, 2022
273a732
change version
VaghinakDev Mar 17, 2022
e726512
added test
VaghinakDev Mar 17, 2022
2820c91
Update version.py
VaghinakDev Mar 17, 2022
47d838f
new version
VaghinakDev Mar 17, 2022
968c31e
Update version.py
VaghinakDev Mar 17, 2022
df0879c
Merge pull request #419 from superannotateai/friday
VaghinakDev Mar 17, 2022
6b97c08
Update version.py
VaghinakDev Mar 17, 2022
1c98347
Update version.py
VaghinakDev Mar 17, 2022
91f87e7
fix cli
VaghinakDev Mar 18, 2022
510984d
Merge pull request #421 from superannotateai/friday
VaghinakDev Mar 18, 2022
df691e0
Update version.py
VaghinakDev Mar 18, 2022
8202f83
Merge branch 'master' into develop
VaghinakDev Mar 20, 2022
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
5 changes: 4 additions & 1 deletion docs/source/superannotate.sdk.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ________
.. autofunction:: superannotate.attach_image_urls_to_project
.. autofunction:: superannotate.upload_images_from_public_urls_to_project
.. autofunction:: superannotate.attach_document_urls_to_project
.. autofunction:: superannotate.attach_items_from_integrated_storage
.. autofunction:: superannotate.upload_image_to_project
.. autofunction:: superannotate.delete_annotations
.. _ref_upload_images_from_folder_to_project:
Expand Down Expand Up @@ -92,6 +93,7 @@ ______
.. autofunction:: superannotate.add_annotation_bbox_to_image
.. autofunction:: superannotate.add_annotation_point_to_image
.. autofunction:: superannotate.add_annotation_comment_to_image
.. autofunction:: superannotate.upload_priority_scores

----------

Expand All @@ -107,10 +109,11 @@ __________________

----------

Team contributors
Team
_________________

.. autofunction:: superannotate.get_team_metadata
.. autofunction:: superannotate.get_integrations
.. autofunction:: superannotate.invite_contributors_to_team
.. autofunction:: superannotate.search_team_contributors

Expand Down
2 changes: 1 addition & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
superannotate_schemas>=1.0.38.b1
superannotate_schemas>=1.0.40b3
9 changes: 9 additions & 0 deletions src/superannotate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
attach_document_urls_to_project,
)
from superannotate.lib.app.interface.sdk_interface import attach_image_urls_to_project
from superannotate.lib.app.interface.sdk_interface import attach_items_from_integrated_storage
from superannotate.lib.app.interface.sdk_interface import attach_video_urls_to_project
from superannotate.lib.app.interface.sdk_interface import benchmark
from superannotate.lib.app.interface.sdk_interface import clone_project
Expand Down Expand Up @@ -56,6 +57,7 @@
from superannotate.lib.app.interface.sdk_interface import get_folder_metadata
from superannotate.lib.app.interface.sdk_interface import get_image_annotations
from superannotate.lib.app.interface.sdk_interface import get_image_metadata
from superannotate.lib.app.interface.sdk_interface import get_integrations
from superannotate.lib.app.interface.sdk_interface import (
get_project_and_folder_metadata,
)
Expand Down Expand Up @@ -103,6 +105,9 @@
from superannotate.lib.app.interface.sdk_interface import (
upload_preannotations_from_folder_to_project,
)
from superannotate.lib.app.interface.sdk_interface import (
upload_priority_scores,
)
from superannotate.lib.app.interface.sdk_interface import upload_video_to_project
from superannotate.lib.app.interface.sdk_interface import (
upload_videos_from_folder_to_project,
Expand Down Expand Up @@ -132,6 +137,9 @@
# annotations
"get_annotations",
"get_annotations_per_frame",
# integrations
"get_integrations",
"attach_items_from_integrated_storage",
# converters
"convert_json_version",
"import_annotation",
Expand All @@ -151,6 +159,7 @@
"clone_project",
"share_project",
"delete_project",
"upload_priority_scores",
# Images Section
"search_images",
"copy_image",
Expand Down
9 changes: 3 additions & 6 deletions src/superannotate/lib/app/interface/cli_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
from lib.infrastructure.repositories import ConfigRepository


controller = Controller()
controller.retrieve_configs(constances.CONFIG_FILE_LOCATION)


class CLIFacade(BaseInterfaceFacade):
"""
Expand Down Expand Up @@ -124,12 +121,12 @@ def export_project(
folders = None
if folder_name:
folders = [folder_name]
export_res = controller.prepare_export(
export_res = Controller.get_default().prepare_export(
project_name, folders, include_fuse, False, annotation_statuses
)
export_name = export_res.data["name"]

use_case = controller.download_export(
use_case = Controller.get_default().download_export(
project_name=project_name,
export_name=export_name,
folder_path=folder,
Expand Down Expand Up @@ -189,7 +186,7 @@ def _upload_annotations(
):
project_folder_name = project
project_name, folder_name = split_project_path(project)
project = controller.get_project_metadata(project_name=project_name).data
project = Controller.get_default().get_project_metadata(project_name=project_name).data
if not format:
format = "SuperAnnotate"
if not dataset_name and format == "COCO":
Expand Down
74 changes: 73 additions & 1 deletion src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@
from lib.app.serializers import SettingsSerializer
from lib.app.serializers import TeamSerializer
from lib.core import LIMITED_FUNCTIONS
from lib.core.entities.integrations import IntegrationEntity
from lib.core.entities.project_entities import AnnotationClassEntity
from lib.core.enums import ImageQuality
from lib.core.exceptions import AppException
from lib.core.types import AttributeGroup
from lib.core.types import MLModel
from lib.core.types import PriorityScore
from lib.core.types import Project
from lib.infrastructure.controller import Controller
from pydantic import conlist
Expand Down Expand Up @@ -189,7 +191,7 @@ def create_project_from_metadata(project_metadata: Project):
project_metadata = project_metadata.dict()
response = Controller.get_default().create_project(
name=project_metadata["name"],
description=project_metadata["description"],
description=project_metadata.get("description"),
project_type=project_metadata["type"],
settings=project_metadata.get("settings", []),
annotation_classes=project_metadata.get("classes", []),
Expand Down Expand Up @@ -1572,6 +1574,8 @@ def create_annotation_class(
attribute_groups=attribute_groups,
class_type=class_type,
)
if response.errors:
raise AppException(response.errors)
return BaseSerializers(response.data).serialize()


Expand Down Expand Up @@ -2900,3 +2904,71 @@ def get_annotations_per_frame(project: NotEmptyStr, video: NotEmptyStr, fps: int
if response.errors:
raise AppException(response.errors)
return response.data


@Trackable
@validate_arguments
def upload_priority_scores(project: NotEmptyStr, scores: List[PriorityScore]):
"""Returns per frame annotations for the given video.

:param project: project name or folder path (e.g., “project1/folder1”)
:type project: str

:param scores: list of score objects
:type scores: list of dicts

:return: lists of uploaded, skipped items
:rtype: tuple (2 members) of lists of strs
"""
project_name, folder_name = extract_project_folder(project)
project_folder_name = project
response = Controller.get_default().upload_priority_scores(project_name, folder_name, scores, project_folder_name)
if response.errors:
raise AppException(response.errors)
return response.data


@Trackable
@validate_arguments
def get_integrations():
"""Get all integrations per team

:return: metadata objects of all integrations of the team.
:rtype: list of dicts
"""
response = Controller.get_default().get_integrations()
if response.errors:
raise AppException(response.errors)
integrations = response.data
return BaseSerializers.serialize_iterable(integrations, ("name", "type", "root"))


@Trackable
@validate_arguments
def attach_items_from_integrated_storage(
project: NotEmptyStr,
integration: Union[NotEmptyStr, IntegrationEntity],
folder_path: Optional[NotEmptyStr] = None
):
"""Link images from integrated external storage to SuperAnnotate.

:param project: project name or folder path where items should be attached (e.g., “project1/folder1”).
:type project: str

:param project: project name or folder path where items should be attached (e.g., “project1/folder1”).
:type project: str

:param integration: existing integration name or metadata dict to pull items from.
Mandatory keys in integration metadata’s dict is “name”.
:type integration: str or dict

:param folder_path: Points to an exact folder/directory within given storage.
If None, items are fetched from the root directory.
:type folder_path: str
"""
project_name, folder_name = extract_project_folder(project)
if isinstance(integration, str):
integration = IntegrationEntity(name=integration)
response = Controller.get_default().attach_integrations(project_name, folder_name, integration, folder_path)
if response.errors:
raise AppException(response.errors)
35 changes: 35 additions & 0 deletions src/superannotate/lib/app/mixp/utils/parsers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import lib.core as constances
from lib.app.helpers import extract_project_folder
from lib.core.entities import IntegrationEntity
from lib.core.enums import ProjectType
from lib.infrastructure.controller import Controller

Expand Down Expand Up @@ -1230,3 +1231,37 @@ def get_annotations_per_frame(*args, **kwargs):
"event_name": "get_annotations_per_frame",
"properties": {"Project": project, "fps": fps},
}


def upload_priority_scores(*args, **kwargs):
scores = kwargs.get("scores", args[1])
return {
"event_name": "upload_priority_scores",
"properties": {"Score Count": len(scores)},
}


def get_integrations(*args, **kwargs):
return {
"event_name": "get_integrations",
"properties": {},
}


def attach_items_from_integrated_storage(*args, **kwargs):
project = kwargs.get("project", args[0])
integration = kwargs.get("integration", args[1])
folder_path = kwargs.get("folder_path", args[2])

project_name, _ = extract_project_folder(project)
if isinstance(integration, str):
integration = IntegrationEntity(name=integration)
project = Controller.get_default().get_project_metadata(project_name)
return {
"event_name": "attach_items_from_integrated_storage",
"properties": {
"project_type": ProjectType.get_name(project.project_type),
"integration_name": integration.name,
"folder_path": bool(folder_path)
},
}
45 changes: 38 additions & 7 deletions src/superannotate/lib/app/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from abc import ABC
from typing import Any
from typing import List
from typing import Set
from typing import Union

import superannotate.lib.core as constance
from pydantic import BaseModel
Expand All @@ -11,12 +15,36 @@ class BaseSerializers(ABC):
def __init__(self, entity: BaseEntity):
self._entity = entity

def serialize(self):
if isinstance(self._entity, dict):
return self._entity
if isinstance(self._entity, BaseModel):
return self._entity.dict(by_alias=True)
return self._entity.to_dict()
def serialize(self, fields: List[str] = None, by_alias: bool = True, flat: bool = False):
return self._serialize(self._entity, fields, by_alias, flat)

@staticmethod
def _serialize(entity: Any, fields: List[str] = None, by_alias: bool = False, flat: bool = False):
if isinstance(entity, dict):
return entity
if isinstance(entity, BaseModel):
if fields:
fields = set(fields)
if len(fields) == 1:
if flat:
return entity.dict(include=fields, by_alias=by_alias)[next(iter(fields))]
return entity.dict(include=fields, by_alias=by_alias)
return entity.dict(include=fields, by_alias=by_alias)
return entity.dict(by_alias=by_alias)
return entity.to_dict()

@classmethod
def serialize_iterable(
cls,
data: List[Any],
fields: Union[List[str], Set[str]] = None,
by_alias: bool = False,
flat: bool = False
) -> List[Any]:
serialized_data = []
for i in data:
serialized_data.append(cls._serialize(i, fields, by_alias, flat))
return serialized_data


class UserSerializer(BaseSerializers):
Expand All @@ -43,6 +71,10 @@ class ProjectSerializer(BaseSerializers):
def serialize(self):
data = super().serialize()
data["type"] = constance.ProjectType.get_name(data["type"])
if data.get("status"):
data["status"] = constance.ProjectStatus.get_name(data["status"])
else:
data["status"] = "Undefined"
if data.get("upload_state"):
data["upload_state"] = constance.UploadState(data["upload_state"]).name
if data.get("users"):
Expand Down Expand Up @@ -114,4 +146,3 @@ def serialize(self):
if data["attribute"] == "ImageQuality":
data["value"] = constance.ImageQuality.get_name(data["value"])
return data

2 changes: 2 additions & 0 deletions src/superannotate/lib/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from superannotate.lib.core.enums import AnnotationStatus
from superannotate.lib.core.enums import ImageQuality
from superannotate.lib.core.enums import ProjectStatus
from superannotate.lib.core.enums import ProjectType
from superannotate.lib.core.enums import SegmentationStatus
from superannotate.lib.core.enums import TrainingStatus
Expand Down Expand Up @@ -127,6 +128,7 @@
INVALID_JSON_MESSAGE = "Invalid json"

__alL__ = (
ProjectStatus,
ProjectType,
UserRole,
UploadState,
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
@@ -1,3 +1,4 @@
from lib.core.entities.integrations import IntegrationEntity
from lib.core.entities.project_entities import AnnotationClassEntity
from lib.core.entities.project_entities import BaseEntity
from lib.core.entities.project_entities import ConfigEntity
Expand Down Expand Up @@ -33,6 +34,7 @@
"UserEntity",
"TeamEntity",
"MLModelEntity",
"IntegrationEntity",
# annotations
"DocumentAnnotation",
"VideoAnnotation",
Expand Down
9 changes: 9 additions & 0 deletions src/superannotate/lib/core/entities/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from datetime import datetime

from pydantic import BaseModel
from pydantic import Field


class TimedBaseModel(BaseModel):
created_at: datetime = Field(None, alias="createdAt")
updated_at: datetime = Field(None, alias="updatedAt")
14 changes: 14 additions & 0 deletions src/superannotate/lib/core/entities/integrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from lib.core.entities.base import TimedBaseModel
from pydantic import Field


class IntegrationEntity(TimedBaseModel):
id: int = None
user_id: str = None
name: str
type: str = "aws"
root: str = Field(None, alias="bucket_name")
source: int = None

class Config:
arbitrary_types_allowed = True
Loading