Skip to content

Commit 28859b0

Browse files
committed
Add name support for get_catalog_slice() and get_catalog_slices()
1 parent 3fe2b9e commit 28859b0

File tree

2 files changed

+178
-10
lines changed

2 files changed

+178
-10
lines changed

libs/labelbox/src/labelbox/client.py

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,18 +1808,16 @@ def _format_failed_rows(
18081808

18091809
def get_catalog(self) -> Catalog:
18101810
return Catalog(client=self)
1811+
18111812

1812-
def get_catalog_slice(self, slice_id) -> CatalogSlice:
1813+
def get_catalog_slices(self) -> List[CatalogSlice]:
18131814
"""
1814-
Fetches a Catalog Slice by ID.
1815-
1816-
Args:
1817-
slice_id (str): The ID of the Slice
1815+
Fetches all slices of the given entity type.
18181816
Returns:
1819-
CatalogSlice
1817+
List[CatalogSlice]: A list of CatalogSlice objects.
18201818
"""
1821-
query_str = """query getSavedQueryPyApi($id: ID!) {
1822-
getSavedQuery(id: $id) {
1819+
query_str = """query GetCatalogSavedQueriesPyApi {
1820+
catalogSavedQueries {
18231821
id
18241822
name
18251823
description
@@ -1828,9 +1826,64 @@ def get_catalog_slice(self, slice_id) -> CatalogSlice:
18281826
updatedAt
18291827
}
18301828
}
1829+
"""
1830+
res = self.execute(query_str)
1831+
return [CatalogSlice(self, sl) for sl in res["catalogSavedQueries"]]
1832+
1833+
1834+
def get_catalog_slice(
1835+
self,
1836+
slice_id: Optional[str] = None,
1837+
slice_name: Optional[str] = None
1838+
) -> Union[CatalogSlice, List[CatalogSlice]]:
18311839
"""
1832-
res = self.execute(query_str, {"id": slice_id})
1833-
return Entity.CatalogSlice(self, res["getSavedQuery"])
1840+
Fetches a Slice using either the slice ID or the slice name.
1841+
1842+
Args:
1843+
slice_id (Optional[str]): The ID of the Slice.
1844+
slice_name (Optional[str]): The name of the Slice.
1845+
1846+
Returns:
1847+
Union[CatalogSlice, List[CatalogSlice], ModelSlice, List[ModelSlice]]:
1848+
The corresponding Slice object or list of Slice objects.
1849+
1850+
Raises:
1851+
ValueError: If neither or both id and name are provided.
1852+
ResourceNotFoundError: If the slice is not found.
1853+
"""
1854+
if (slice_id is None and slice_name is None) or (slice_id is not None and slice_name is not None):
1855+
raise ValueError("Provide exactly one of id or name")
1856+
1857+
if slice_id is not None:
1858+
query_str = """query getSavedQueryPyApi($id: ID!) {
1859+
getSavedQuery(id: $id) {
1860+
id
1861+
name
1862+
description
1863+
filter
1864+
createdAt
1865+
updatedAt
1866+
}
1867+
}
1868+
"""
1869+
1870+
res = self.execute(query_str, {"id": slice_id})
1871+
if res is None:
1872+
raise ResourceNotFoundError(CatalogSlice, {"id": slice_id})
1873+
1874+
return CatalogSlice(self, res["getSavedQuery"])
1875+
1876+
else:
1877+
slices = self.get_catalog_slices()
1878+
matches = [s for s in slices if s.name == slice_name]
1879+
1880+
if not matches:
1881+
raise ResourceNotFoundError(CatalogSlice, {"name": slice_name})
1882+
elif len(matches) > 1:
1883+
return matches
1884+
else:
1885+
return matches[0]
1886+
18341887

18351888
def is_feature_schema_archived(
18361889
self, ontology_id: str, feature_schema_id: str
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import pytest
2+
from typing import Optional
3+
from labelbox import Client, CatalogSlice
4+
5+
6+
def _create_catalog_slice(client: Client, name: str, description: Optional[str] = None) -> str:
7+
"""Creates a catalog slice for testing purposes.
8+
9+
Args:
10+
client (Client): Labelbox client instance
11+
name (str): Name of the catalog slice
12+
description (str): Description of the catalog slice
13+
14+
Returns:
15+
str: ID of the created catalog slice
16+
"""
17+
18+
mutation = """mutation CreateCatalogSlicePyApi($name: String!, $description: String, $query: SearchServiceQuery!, $sorting: [SearchServiceSorting!]) {
19+
createCatalogSavedQuery(
20+
args: {name: $name, description: $description, filter: $query, sorting: $sorting}
21+
) {
22+
id
23+
name
24+
description
25+
filter
26+
sorting
27+
catalogCount {
28+
count
29+
}
30+
}
31+
}
32+
"""
33+
34+
params = {
35+
"description": description,
36+
"name": name,
37+
"query": [
38+
{
39+
"type": "media_attribute_asset_type",
40+
"assetType": {
41+
"type": "asset_type",
42+
"assetTypes": [
43+
"image"
44+
]
45+
}
46+
}
47+
],
48+
"sorting": [
49+
{
50+
"field": {
51+
"field": "dataRowCreatedAt",
52+
"verboseName": "Created At"
53+
},
54+
"direction": "DESC",
55+
"metadataSchemaId": None
56+
}
57+
]
58+
}
59+
60+
result = client.execute(mutation, params, experimental=True)
61+
62+
return result["createCatalogSavedQuery"].get("id")
63+
64+
65+
def _delete_catalog_slice(client, slice_id: str) -> bool:
66+
67+
mutation = """mutation DeleteCatalogSlicePyApi($id: ID!) {
68+
deleteSavedQuery(args: { id: $id }) {
69+
success
70+
}
71+
}
72+
"""
73+
74+
params = {
75+
"id": slice_id
76+
}
77+
78+
operation_done = True
79+
try:
80+
client.execute(mutation, params, experimental=True)
81+
except Exception as ex:
82+
operation_done = False
83+
84+
return operation_done
85+
86+
87+
def test_get_slice(client):
88+
89+
# Pre-cleaning
90+
slices = ( s for s in client.get_catalog_slices()
91+
if s.name in ["Test Slice 1", "Test Slice 2"])
92+
for slice in slices:
93+
_delete_catalog_slice(client, slice.id)
94+
95+
# Create slices
96+
slice_id_1 = _create_catalog_slice(client, "Test Slice 1", "Slice created for SDK test.")
97+
slice_id_2 = _create_catalog_slice(client, "Test Slice 2", "Slice created for SDK test.")
98+
# Create slice 2b - with the same name as slice 2
99+
slice_id_2b = _create_catalog_slice(client, "Test Slice 2", "Slice created for SDK test.")
100+
101+
# Assert get slice 1 by ID
102+
slice_1 = client.get_catalog_slice(slice_id_1)
103+
assert isinstance(slice_1, CatalogSlice)
104+
105+
slice_1 = client.get_catalog_slice(slice_name="Test Slice 1")
106+
assert isinstance(slice_1, CatalogSlice)
107+
108+
slices_2 = client.get_catalog_slice(slice_name="Test Slice 2")
109+
assert len(slices_2) == 2
110+
assert isinstance(slices_2, list) and all([isinstance(item, CatalogSlice) for item in slices_2])
111+
112+
# Cleaning - Delete slices
113+
_delete_catalog_slice(client, slice_id_1)
114+
_delete_catalog_slice(client, slice_id_2)
115+
_delete_catalog_slice(client, slice_id_2b)

0 commit comments

Comments
 (0)