Skip to content

Commit 2c738f2

Browse files
ml-evsclaude
andcommitted
Refactor DatalabClient methods to use centralized error handling
Replace manual error handling in all HTTP request methods with calls to centralized _get(), _post(), and _put() methods from the base class. Changes: - Remove repetitive status code and JSON status checks - Use _get() for GET requests: get_info, get_block_info, get_items, search_items, get_item, get_collection - Use _post() for POST requests: create_item, update_item, get_block, upload_file, create_data_block, _update_data_block - Use _put() for PUT requests: create_collection - Maintain existing custom error handling for authenticate() method - Significantly reduce code duplication and improve maintainability 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 73ebba4 commit 2c738f2

File tree

1 file changed

+20
-120
lines changed

1 file changed

+20
-120
lines changed

src/datalab_api/__init__.py

Lines changed: 20 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def get_info(self) -> dict[str, Any]:
3434
3535
"""
3636
info_url = f"{self.datalab_api_url}/info"
37-
info_resp = self.session.get(info_url, follow_redirects=True)
38-
self.info = info_resp.json()["data"]
37+
info_data = self._get(info_url)
38+
self.info = info_data["data"]
3939
return self.info
4040

4141
def authenticate(self):
@@ -60,12 +60,8 @@ def get_block_info(self) -> list[dict[str, Any]]:
6060
6161
"""
6262
block_info_url = f"{self.datalab_api_url}/info/blocks"
63-
block_info_resp = self.session.get(block_info_url, follow_redirects=True)
64-
if block_info_resp.status_code != 200:
65-
raise RuntimeError(
66-
f"Failed to list block information at {block_info_url}: {block_info_resp.status_code=}."
67-
)
68-
self.block_info = block_info_resp.json()["data"]
63+
block_info_data = self._get(block_info_url)
64+
self.block_info = block_info_data["data"]
6965
return self.block_info
7066

7167
def get_items(self, item_type: str | None = "samples") -> list[dict[str, Any]]:
@@ -90,14 +86,7 @@ def get_items(self, item_type: str | None = "samples") -> list[dict[str, Any]]:
9086
item_type = "samples"
9187

9288
items_url = f"{self.datalab_api_url}/{endpoint_type_map.get(item_type, item_type.replace('_', '-'))}"
93-
items_resp = self.session.get(items_url, follow_redirects=True)
94-
if items_resp.status_code != 200:
95-
raise RuntimeError(
96-
f"Failed to list items with {item_type=} at {items_url}: {items_resp.status_code=}. Check the item type is correct."
97-
)
98-
items = items_resp.json()
99-
if items["status"] != "success":
100-
raise RuntimeError(f"Failed to list items at {items_url}: {items['status']!r}.")
89+
items = self._get(items_url)
10190

10291
if item_type in items:
10392
# Old approach
@@ -127,15 +116,7 @@ def search_items(
127116
search_items_url = (
128117
f"{self.datalab_api_url}/search-items?query={query}&types={','.join(item_types)}"
129118
)
130-
items_resp = self.session.get(search_items_url, follow_redirects=True)
131-
if items_resp.status_code != 200:
132-
raise RuntimeError(
133-
f"Failed to search items with {item_types=} at {search_items_url}: {items_resp.status_code=}"
134-
)
135-
items = items_resp.json()
136-
if items["status"] != "success":
137-
raise RuntimeError(f"Failed to list items at {search_items_url}: {items['status']!r}.")
138-
119+
items = self._get(search_items_url)
139120
return items["items"]
140121

141122
def create_item(
@@ -173,29 +154,11 @@ def create_item(
173154
new_item["collections"].append({"immutable_id": collection_immutable_id})
174155

175156
create_item_url = f"{self.datalab_api_url}/new-sample/"
176-
create_item_resp = self.session.post(
157+
created_item = self._post(
177158
create_item_url,
178159
json={"new_sample_data": new_item, "generate_id_automatically": item_id is None},
179-
follow_redirects=True,
180160
)
181-
try:
182-
created_item = create_item_resp.json()
183-
if create_item_resp.status_code == 409:
184-
raise DuplicateItemError(
185-
f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
186-
)
187-
if created_item["status"] != "success":
188-
if "DuplicateKeyError" in created_item["message"]:
189-
raise DuplicateItemError(
190-
f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
191-
)
192-
raise RuntimeError(f"Failed to create item at {create_item_url}: {created_item}.")
193-
return created_item["sample_list_entry"]
194-
195-
except Exception as exc:
196-
raise exc.__class__(
197-
f"Failed to create item {item_id=} with data {item_data=} at {create_item_url}: {create_item_resp.status_code=}, {create_item_resp.content}. Check the item information is correct."
198-
) from exc
161+
return created_item["sample_list_entry"]
199162

200163
def update_item(self, item_id: str, item_data: dict[str, Any]) -> dict[str, Any]:
201164
"""Update an item with the given item data.
@@ -210,20 +173,7 @@ def update_item(self, item_id: str, item_data: dict[str, Any]) -> dict[str, Any]
210173
"""
211174
update_item_data = {"item_id": item_id, "data": item_data}
212175
update_item_url = f"{self.datalab_api_url}/save-item/"
213-
update_item_resp = self.session.post(
214-
update_item_url,
215-
json=update_item_data,
216-
follow_redirects=True,
217-
)
218-
if update_item_resp.status_code != 200:
219-
raise RuntimeError(
220-
f"Failed to update item {item_id=} at {update_item_url}: {update_item_resp.status_code=}. Check the item information is correct."
221-
)
222-
updated_item = update_item_resp.json()
223-
if updated_item["status"] != "success":
224-
raise RuntimeError(
225-
f"Failed to update item at {update_item_url}: {updated_item['status']!r}."
226-
)
176+
updated_item = self._post(update_item_url, json=update_item_data)
227177
return updated_item
228178

229179
def get_item(
@@ -255,16 +205,7 @@ def get_item(
255205
else:
256206
item_url = f"{self.datalab_api_url}/get-item-data/{item_id}"
257207

258-
item_resp = self.session.get(item_url, follow_redirects=True)
259-
260-
if item_resp.status_code != 200:
261-
raise RuntimeError(
262-
f"Failed to find item {item_id=}, {refcode=} {item_url}: {item_resp.status_code=}. Check the item information is correct."
263-
)
264-
265-
item = item_resp.json()
266-
if item["status"] != "success":
267-
raise RuntimeError(f"Failed to get item at {item_url}: {item['status']!r}.")
208+
item = self._get(item_url)
268209

269210
# Filter out any deleted blocks
270211
item["item_data"]["blocks_obj"] = {
@@ -324,15 +265,7 @@ def get_block(self, item_id: str, block_id: str, block_data: dict[str, Any]) ->
324265
"block_id": block_id,
325266
"save_to_db": False,
326267
}
327-
block_resp = self.session.post(block_url, json=block_request, follow_redirects=True)
328-
if block_resp.status_code != 200:
329-
raise RuntimeError(
330-
f"Failed to find block {block_id=} for item {item_id=} at {block_url}: {block_resp.status_code=}. Check the block information is correct."
331-
)
332-
333-
block = block_resp.json()
334-
if block["status"] != "success":
335-
raise RuntimeError(f"Failed to get block at {block_url}: {block['status']!r}.")
268+
block = self._post(block_url, json=block_request)
336269
return block["new_block_data"]
337270

338271
def upload_file(self, item_id: str, file_path: Path | str) -> dict[str, Any]:
@@ -354,21 +287,12 @@ def upload_file(self, item_id: str, file_path: Path | str) -> dict[str, Any]:
354287
upload_url = f"{self.datalab_api_url}/upload-file/"
355288
with open(file_path, "rb") as file:
356289
files = {"file": (file_path.name, file)}
357-
upload_resp = self.session.post(
290+
upload = self._post(
358291
upload_url,
359292
files=files,
360293
data={"item_id": item_id, "replace_file": None},
361-
follow_redirects=True,
294+
expected_status=201,
362295
)
363-
if upload_resp.status_code != 201:
364-
raise RuntimeError(
365-
f"Failed to upload file {file_path=} to item {item_id=} at {upload_url}: {upload_resp.status_code=}. Check the file information is correct."
366-
)
367-
368-
upload = upload_resp.json()
369-
if upload["status"] != "success":
370-
raise RuntimeError(f"Failed to upload file at {upload_url}: {upload['status']!r}.")
371-
372296
return upload
373297

374298
def create_data_block(
@@ -418,12 +342,7 @@ def create_data_block(
418342
f"Not all IDs {file_ids=} are attached to item {item_id=}: {attached_file_ids=}"
419343
)
420344

421-
block_resp = self.session.post(blocks_url, json=payload, follow_redirects=True)
422-
if block_resp.status_code != 200:
423-
raise RuntimeError(
424-
f"Failed to create block {block_type=} for item {item_id=}:\n{block_resp.text}"
425-
)
426-
block_data = block_resp.json()["new_block_obj"]
345+
block_data = self._post(blocks_url, json=payload)["new_block_obj"]
427346

428347
if file_ids:
429348
block_data = self._update_data_block(
@@ -480,11 +399,8 @@ def _update_data_block(
480399
"save_to_db": True,
481400
}
482401

483-
resp = self.session.post(blocks_url, json=payload, follow_redirects=True)
484-
if resp.status_code != 200:
485-
raise RuntimeError(f"Failed to update block {block_type=}:\n{resp.text}")
486-
487-
return resp.json()["new_block_data"]
402+
resp = self._post(blocks_url, json=payload)
403+
return resp["new_block_data"]
488404

489405
def get_collection(self, collection_id: str) -> tuple[dict[str, Any], list[dict[str, Any]]]:
490406
"""Get a collection with a given ID.
@@ -498,16 +414,7 @@ def get_collection(self, collection_id: str) -> tuple[dict[str, Any], list[dict[
498414
499415
"""
500416
collection_url = f"{self.datalab_api_url}/collections/{collection_id}"
501-
collection_resp = self.session.get(collection_url, follow_redirects=True)
502-
if collection_resp.status_code != 200:
503-
raise RuntimeError(
504-
f"Failed to find collection {collection_id=} at {collection_url}: {collection_resp.status_code=}. Check the collection ID is correct."
505-
)
506-
collection = collection_resp.json()
507-
if collection["status"] != "success":
508-
raise RuntimeError(
509-
f"Failed to get collection at {collection_url}: {collection['status']!r}."
510-
)
417+
collection = self._get(collection_url)
511418
return collection["data"], collection["child_items"]
512419

513420
def create_collection(
@@ -527,16 +434,9 @@ def create_collection(
527434
new_collection = collection_data
528435
new_collection.update({"collection_id": collection_id, "type": "collections"})
529436

530-
collection_resp = self.session.put(
437+
created_collection = self._put(
531438
collection_url,
532439
json={"data": new_collection},
533-
follow_redirects=True,
440+
expected_status=201,
534441
)
535-
536-
if collection_resp.status_code != 201 or collection_resp.json()["status"] != "success":
537-
raise RuntimeError(
538-
f"Failed to create collection {collection_id=} at {collection_url}: {collection_resp.status_code=}. Check the collection information is correct: {collection_resp.content}"
539-
)
540-
541-
created_collection = collection_resp.json()["data"]
542-
return created_collection
442+
return created_collection["data"]

0 commit comments

Comments
 (0)