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
14 changes: 10 additions & 4 deletions hasty/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,29 @@ def _set_prop_values(self, data):
self._values = data["values"]

@staticmethod
def validate_type(attribute_type):
def validate_types(attribute_type, subject_type):
if attribute_type not in ['SELECTION', 'MULTIPLE-SELECTION', 'TEXT', 'INT', 'FLOAT', 'BOOL']:
raise ValidationException('Attribute type should be one of the following '
'[SELECTION, MULTIPLE-SELECTION, TEXT, INT, FLOAT, BOOL]')
if subject_type not in ["IMAGE", "VIDEO", "LABEL", "SEGMENT"]:
raise ValidationException("Subject type should be one of the following "
"[IMAGE, VIDEO, LABEL, SEGMENT]")

@staticmethod
def create(requester, project_id: str, name: str, attribute_type: str, description: Optional[str] = None,
def create(requester, project_id: str, name: str, attribute_type: str, subject_type: str, description: Optional[str] = None,
norder: Optional[float] = None, values: List[str] = None):
Attribute.validate_type(attribute_type)
Attribute.validate_types(attribute_type, subject_type)
json_data = {"name": name,
"type": attribute_type,
"subject_type": subject_type,
"description": description,
"values": [{"value": v} for v in values],
"norder": norder}

res = requester.post(Attribute.endpoint.format(project_id=project_id), json_data=json_data)
return Attribute(requester, res, {"project_id": project_id})

def edit(self, name: str, attribute_type: str, description: Optional[str] = None,
def edit(self, name: str, attribute_type: str, subject_type: str, description: Optional[str] = None,
norder: Optional[float] = None, values: List[str] = None):
"""
Edit attribute properties
Expand All @@ -117,12 +121,14 @@ def edit(self, name: str, attribute_type: str, description: Optional[str] = None
Args:
name (str): Attribute name
attribute_type (str): Attribute type ['SELECTION', 'MULTIPLE-SELECTION', 'TEXT', 'INT', 'FLOAT', 'BOOL']
subject_type (str): Subject type ['IMAGE', 'VIDEO', 'LABEL', 'SEGMENT']
description (str, optional): Attrbute description
norder (float, optional): Order in the Hasty tool
values (list of str): List of values for SELECTION and MULTIPLE-SELECTION attribute type
"""
json_data = {"name": name,
"type": attribute_type,
"subject_type": subject_type,
"description": description,
"norder": norder,
"values": [{"value": v} for v in values]}
Expand Down
5 changes: 3 additions & 2 deletions hasty/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,19 +283,20 @@ def get_attributes(self):
Attribute.endpoint.format(project_id=self._id),
obj_params={"project_id": self.id})

def create_attribute(self, name: str, attribute_type: str, description: Optional[str] = None,
def create_attribute(self, name: str, attribute_type: str, subject_type: str, description: Optional[str] = None,
norder: Optional[float] = None, values: List[str] = None):
"""
Create attribute, returns :py:class:`~hasty.Attribute` object.

Args:
name (str): Attribute name
attribute_type (str): Attribute type ['SELECTION', 'MULTIPLE-SELECTION', 'TEXT', 'INT', 'FLOAT', 'BOOL']
subject_type (str): Subject type ['IMAGE', 'VIDEO', 'LABEL', 'SEGMENT']
description (str, optional): Attrbute description
norder (float, optional): Order in the Hasty tool
values (list of str): List of values for SELECTION and MULTIPLE-SELECTION attribute type
"""
return Attribute.create(self._requester, self._id, name, attribute_type, description, norder, values)
return Attribute.create(self._requester, self._id, name, attribute_type, subject_type, description, norder, values)

def get_attribute_classes(self):
"""
Expand Down
12 changes: 6 additions & 6 deletions tests/test_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ def test_attributes(self):
attributes = self.project.get_attributes()
self.assertEqual(0, len(attributes), 'Should be no attributes for a new project')
# Create attribute
attr = self.project.create_attribute("attr1", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
attr = self.project.create_attribute("attr1", "SELECTION", "IMAGE", "Some desc", 2, ["v1", "v2", "v3"])
self.validate_attribute(attr, "attr1", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
# Update attribute
attr.edit("attr2", "SELECTION", "Desc2", 3, ["v1", "v2"])
attr.edit("attr2", "SELECTION", "IMAGE", "Desc2", 3, ["v1", "v2"])
self.validate_attribute(attr, "attr2", "SELECTION", "Desc2", 3, ["v1", "v2"])
# Check get attributes
attributes = self.project.get_attributes()
Expand All @@ -40,8 +40,8 @@ def test_attributes(self):
self.assertEqual(0, len(attributes), 'Should not be any attributes')

def test_attribute_class(self):
attr1 = self.project.create_attribute("attr1", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
attr2 = self.project.create_attribute("attr2", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
attr1 = self.project.create_attribute("attr1", "SELECTION", "IMAGE", "Some desc", 2, ["v1", "v2", "v3"])
attr2 = self.project.create_attribute("attr2", "SELECTION", "IMAGE", "Some desc", 2, ["v1", "v2", "v3"])
lc1 = self.project.create_label_class("class1", "#ff00aa99", "object", 2)
lc2 = self.project.create_label_class("class2", "#ff00aa99", "object", 2)
attr_cls = self.project.get_attribute_classes()
Expand All @@ -62,8 +62,8 @@ def test_attribute_class(self):
self.assertEqual(0, len(attr_cls))

def test_label_attributes(self):
attr1 = self.project.create_attribute("attr1", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
attr2 = self.project.create_attribute("attr2", "SELECTION", "Some desc", 2, ["v1", "v2", "v3"])
attr1 = self.project.create_attribute("attr1", "SELECTION", "IMAGE", "Some desc", 2, ["v1", "v2", "v3"])
attr2 = self.project.create_attribute("attr2", "SELECTION", "IMAGE", "Some desc", 2, ["v1", "v2", "v3"])
lc1 = self.project.create_label_class("class1", "#ff00aa99", "object", 2)
self.project.set_attribute_classes([{"attribute_id": attr1.id, "class_id": lc1.id},
{"attribute_id": attr2.id, "class_id": lc1.id}])
Expand Down
Loading