Skip to content

Commit a11886d

Browse files
committed
Added integration id supperot for attach_items
1 parent c1e4e9f commit a11886d

File tree

11 files changed

+63
-12
lines changed

11 files changed

+63
-12
lines changed

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ minversion = 3.7
33
log_cli=true
44
python_files = test_*.py
55
;pytest_plugins = ['pytest_profiling']
6-
addopts = -n auto --dist=loadscope
6+
;addopts = -n auto --dist=loadscope
77

src/superannotate/__init__.py

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

55

6-
__version__ = "4.4.18"
6+
__version__ = "4.4.19dev1"
77

88
sys.path.append(os.path.split(os.path.realpath(__file__))[0])
99

src/superannotate/lib/app/helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def get_s3_annotation_paths(folder_path, s3_bucket, annotation_paths, recursive)
7878

7979
def get_name_url_duplicated_from_csv(csv_path):
8080
image_data = pd.read_csv(csv_path, dtype=str)
81+
image_data.replace({pd.NA: None}, inplace=True)
8182
if "url" not in image_data.columns:
8283
raise AppException("Column 'url' is required")
8384
image_data = image_data[~image_data["url"].isnull()]
@@ -90,7 +91,7 @@ def get_name_url_duplicated_from_csv(csv_path):
9091
else:
9192
image_data["name"] = [str(uuid.uuid4()) for _ in range(len(image_data.index))]
9293

93-
image_data = pd.DataFrame(image_data, columns=["name", "url"])
94+
image_data = pd.DataFrame(image_data, columns=["name", "url", "integration"])
9495
img_names_urls = image_data.to_dict(orient="records")
9596
duplicate_images = []
9697
seen = []

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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from lib.core.entities.classes import AnnotationClassEntity
5151
from lib.core.entities.classes import AttributeGroup
5252
from lib.core.entities.integrations import IntegrationEntity
53+
from lib.core.entities.integrations import IntegrationTypeEnum
5354
from lib.core.enums import ImageQuality
5455
from lib.core.enums import ProjectType
5556
from lib.core.enums import ClassTypeEnum
@@ -64,7 +65,6 @@
6465
from lib.infrastructure.utils import extract_project_folder
6566
from lib.infrastructure.validators import wrap_error
6667

67-
6868
logger = logging.getLogger("sa")
6969

7070
NotEmptyStr = TypeVar("NotEmptyStr", bound=constr(strict=True, min_length=1))
@@ -110,6 +110,7 @@ class PriorityScore(TypedDict):
110110
class Attachment(TypedDict, total=False):
111111
url: Required[str] # noqa
112112
name: NotRequired[str] # noqa
113+
integration: NotRequired[str] # noqa
113114

114115

115116
class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
@@ -2579,25 +2580,48 @@ def attach_items(
25792580
logger.info("Dropping duplicates.")
25802581
unique_attachments = parse_obj_as(List[AttachmentEntity], unique_attachments)
25812582
uploaded, fails, duplicated = [], [], []
2582-
if unique_attachments:
2583+
_unique_attachments = []
2584+
if any(i.integration for i in unique_attachments):
2585+
integtation_item_map = {
2586+
i.name: i
2587+
for i in self.controller.integrations.list().data
2588+
if i.type == IntegrationTypeEnum.CUSTOM
2589+
}
2590+
invalid_integrations = set()
2591+
for attachment in unique_attachments:
2592+
if attachment.integration:
2593+
if attachment.integration in integtation_item_map:
2594+
attachment.integration_id = integtation_item_map[
2595+
attachment.integration
2596+
].id
2597+
else:
2598+
invalid_integrations.add(attachment.integration)
2599+
continue
2600+
_unique_attachments.append(attachment)
2601+
if invalid_integrations:
2602+
logger.error(
2603+
f"The ['{','.join(invalid_integrations)}'] integrations specified for the items doesn't exist in the "
2604+
"list of integrations on the platform. Any associated items will be skipped."
2605+
)
2606+
if _unique_attachments:
25832607
logger.info(
2584-
f"Attaching {len(unique_attachments)} file(s) to project {project}."
2608+
f"Attaching {len(_unique_attachments)} file(s) to project {project}."
25852609
)
25862610
project, folder = self.controller.get_project_folder(
25872611
project_name, folder_name
25882612
)
25892613
response = self.controller.items.attach(
25902614
project=project,
25912615
folder=folder,
2592-
attachments=unique_attachments,
2616+
attachments=_unique_attachments,
25932617
annotation_status=annotation_status,
25942618
)
25952619
if response.errors:
25962620
raise AppException(response.errors)
25972621
uploaded, duplicated = response.data
25982622
fails = [
25992623
attachment.name
2600-
for attachment in unique_attachments
2624+
for attachment in _unique_attachments
26012625
if attachment.name not in uploaded and attachment.name not in duplicated
26022626
]
26032627
return uploaded, fails, duplicated

src/superannotate/lib/core/entities/project.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class TimedBaseModel(BaseModel):
4040
class AttachmentEntity(BaseModel):
4141
name: Optional[str] = Field(default_factory=lambda: str(uuid.uuid4()))
4242
url: str
43+
integration: Optional[str] = None
44+
integration_id: Optional[int] = None
4345

4446
class Config:
4547
extra = Extra.ignore

src/superannotate/lib/core/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class IntegrationTypeEnum(BaseTitledEnum):
171171
AWS = "aws", 1
172172
GCP = "gcp", 2
173173
AZURE = "azure", 3
174+
CUSTOM = "custom", 4
174175

175176

176177
class TrainingStatus(BaseTitledEnum):

src/superannotate/lib/core/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ class PriorityScoreEntity(BaseModel):
3333
class Attachment(BaseModel):
3434
name: str
3535
path: str
36+
integration_id: Optional[int] = None
3637

3738

3839
class AttachmentMeta(BaseModel):
3940
width: Optional[float] = None
4041
height: Optional[float] = None
42+
integration_id: Optional[int] = None

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ def validate_upload_state(self):
410410
raise AppValidationException(constants.ATTACHING_UPLOAD_STATE_ERROR)
411411

412412
@staticmethod
413-
def generate_meta() -> AttachmentMeta:
414-
return AttachmentMeta(width=None, height=None)
413+
def generate_meta(integration_id=None) -> AttachmentMeta:
414+
return AttachmentMeta(width=None, height=None, integration_id=integration_id)
415415

416416
def execute(self) -> Response:
417417
if self.is_valid():
@@ -436,7 +436,9 @@ def execute(self) -> Response:
436436
to_upload.append(
437437
Attachment(name=attachment.name, path=attachment.url)
438438
)
439-
to_upload_meta[attachment.name] = self.generate_meta()
439+
to_upload_meta[attachment.name] = self.generate_meta(
440+
attachment.integration_id
441+
)
440442
if to_upload:
441443
backend_response = self._service_provider.items.attach(
442444
project=self._project,

src/superannotate/lib/infrastructure/services/item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ItemService(BaseItemService):
4040
ProjectType.PIXEL: ImageResponse,
4141
ProjectType.DOCUMENT: DocumentResponse,
4242
ProjectType.POINT_CLOUD: PointCloudResponse,
43-
ProjectType.GEN_AI: ImageResponse
43+
ProjectType.GEN_AI: ImageResponse,
4444
}
4545

4646
def get_by_id(self, item_id, project_id, project_type):
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
url,name,integration
2+
/600x800,ex_1,custom1
3+
/250x420,ex_2,custom1
4+
/1024x768,ex_3,custom4
5+
/300x200,ex_4,custom2
6+
fjvnvjsvnsdjcndsjcndjcs,,

0 commit comments

Comments
 (0)