Skip to content

Commit d64935d

Browse files
authored
Merge pull request #927 from Labelbox/PTDT-1107
[PTDT-1107] Implemented is_feature_schema_archived client function
2 parents 00049d9 + 739d8f9 commit d64935d

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22

33
# Version 3.40.0 (YYYY-MM-DD)
4+
* Added new client method is_feature_schema_archived
5+
* Added new client method unarchive_feature_schema_node
6+
* Added new client method delete_feature_schema_from_ontology
47

58
## Added
69
* Insert newest changelogs here

labelbox/client.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from labelbox.schema.role import Role
3737
from labelbox.schema.slice import CatalogSlice, ModelSlice
3838
from labelbox.schema.queue_mode import QueueMode
39+
from labelbox.schema.ontology import Ontology, DeleteFeatureFromOntologyResult
3940

4041
from labelbox.schema.media_type import MediaType, get_media_type_validation_error
4142

@@ -44,11 +45,6 @@
4445
_LABELBOX_API_KEY = "LABELBOX_API_KEY"
4546

4647

47-
class DeleteFeatureFromOntologyResult:
48-
archived: bool
49-
deleted: bool
50-
51-
5248
class Client:
5349
""" A Labelbox client.
5450
@@ -1578,6 +1574,49 @@ def get_catalog_slice(self, slice_id) -> CatalogSlice:
15781574
res = self.execute(query_str, {'id': slice_id})
15791575
return Entity.CatalogSlice(self, res['getSavedQuery'])
15801576

1577+
def is_feature_schema_archived(self, ontology_id: str,
1578+
feature_schema_id: str) -> bool:
1579+
"""
1580+
Returns true if a feature schema is archived in the specified ontology, returns false otherwise.
1581+
1582+
Args:
1583+
feature_schema_id (str): The ID of the feature schema
1584+
ontology_id (str): The ID of the ontology
1585+
Returns:
1586+
bool
1587+
"""
1588+
1589+
ontology_endpoint = self.rest_endpoint + "/ontologies/" + urllib.parse.quote(
1590+
ontology_id)
1591+
response = requests.get(
1592+
ontology_endpoint,
1593+
headers=self.headers,
1594+
)
1595+
1596+
if response.status_code == requests.codes.ok:
1597+
feature_schema_nodes = response.json()['featureSchemaNodes']
1598+
tools = feature_schema_nodes['tools']
1599+
classifications = feature_schema_nodes['classifications']
1600+
relationships = feature_schema_nodes['relationships']
1601+
feature_schema_node_list = tools + classifications + relationships
1602+
filtered_feature_schema_nodes = [
1603+
feature_schema_node
1604+
for feature_schema_node in feature_schema_node_list
1605+
if feature_schema_node['featureSchemaId'] == feature_schema_id
1606+
]
1607+
if filtered_feature_schema_nodes:
1608+
return bool(filtered_feature_schema_nodes[0]['archived'])
1609+
else:
1610+
raise labelbox.exceptions.LabelboxError(
1611+
"The specified feature schema was not in the ontology.")
1612+
1613+
elif response.status_code == 404:
1614+
raise labelbox.exceptions.ResourceNotFoundError(
1615+
Ontology, ontology_id)
1616+
else:
1617+
raise labelbox.exceptions.LabelboxError(
1618+
"Failed to get the feature schema archived status.")
1619+
15811620
def get_model_slice(self, slice_id) -> ModelSlice:
15821621
"""
15831622
Fetches a Model Slice by ID.

labelbox/schema/ontology.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@
1111
from labelbox.exceptions import InconsistentOntologyException
1212
from labelbox.orm.db_object import DbObject
1313
from labelbox.orm.model import Field, Relationship
14+
import json
1415

1516
FeatureSchemaId: Type[str] = constr(min_length=25, max_length=25)
1617
SchemaId: Type[str] = constr(min_length=25, max_length=25)
1718

1819

20+
class DeleteFeatureFromOntologyResult:
21+
archived: bool
22+
deleted: bool
23+
24+
def __str__(self):
25+
return "<%s %s>" % (self.__class__.__name__.split(".")[-1],
26+
json.dumps(self.__dict__))
27+
28+
1929
class FeatureSchema(DbObject):
2030
name = Field.String("name")
2131
color = Field.String("name")

tests/integration/test_ontology.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@
66
import time
77

88

9+
def test_feature_schema_is_not_archived(client, ontology):
10+
feature_schema_to_check = ontology.normalized['tools'][0]
11+
result = client.is_feature_schema_archived(
12+
ontology.uid, feature_schema_to_check['featureSchemaId'])
13+
assert result == False
14+
15+
16+
def test_feature_schema_is_archived(client, configured_project_with_label):
17+
project, _, _, label = configured_project_with_label
18+
ontology = project.ontology()
19+
feature_schema_id = ontology.normalized['tools'][0]['featureSchemaId']
20+
result = client.delete_feature_schema_from_ontology(ontology.uid,
21+
feature_schema_id)
22+
assert result.archived == True and result.deleted == False
23+
assert client.is_feature_schema_archived(ontology.uid,
24+
feature_schema_id) == True
25+
26+
27+
def test_is_feature_schema_archived_for_non_existing_feature_schema(
28+
client, ontology):
29+
with pytest.raises(
30+
Exception,
31+
match="The specified feature schema was not in the ontology"):
32+
client.is_feature_schema_archived(ontology.uid,
33+
'invalid-feature-schema-id')
34+
35+
36+
def test_is_feature_schema_archived_for_non_existing_ontology(client, ontology):
37+
feature_schema_to_unarchive = ontology.normalized['tools'][0]
38+
with pytest.raises(
39+
Exception,
40+
match="Resource 'Ontology' not found for params: 'invalid-ontology'"
41+
):
42+
client.is_feature_schema_archived(
43+
'invalid-ontology', feature_schema_to_unarchive['featureSchemaId'])
44+
45+
946
def test_delete_tool_feature_from_ontology(client, ontology):
1047
feature_schema_to_delete = ontology.normalized['tools'][0]
1148
assert len(ontology.normalized['tools']) == 2

0 commit comments

Comments
 (0)