datalab-api 0.2.10__tar.gz → 0.2.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datalab-api
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: A Python API for instances of the datalab data management platform (https://github.com/datalab-org/datalab).
5
5
  Author-email: Matthew Evans <matthew@ml-evs.science>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: homepage, https://github.com/datalab-org/datalab-api
8
8
  Project-URL: repository, https://github.com/datalab-org/datalab-api
9
9
  Project-URL: documentation, https://datalab-python-api.readthedocs.io
@@ -7,7 +7,7 @@ name = "datalab-api"
7
7
  readme = "README.md"
8
8
  description = "A Python API for instances of the datalab data management platform (https://github.com/datalab-org/datalab)."
9
9
  keywords = []
10
- license = { text = "MIT" }
10
+ license = "MIT"
11
11
  authors = [{ name = "Matthew Evans", email = "matthew@ml-evs.science" }]
12
12
  dynamic = ["version"]
13
13
  classifiers = [
@@ -83,9 +83,17 @@ class DatalabClient(BaseDatalabClient):
83
83
  A list of items of the given type.
84
84
 
85
85
  """
86
+ endpoint_type_map = {
87
+ "cells": "samples",
88
+ "samples": "samples",
89
+ "starting_materials": "starting-materials",
90
+ "equipment": "equipment",
91
+ }
92
+
86
93
  if item_type is None:
87
94
  item_type = "samples"
88
- items_url = f"{self.datalab_api_url}/{item_type}"
95
+
96
+ items_url = f"{self.datalab_api_url}/{endpoint_type_map.get(item_type, item_type.replace('_', '-'))}"
89
97
  items_resp = self.session.get(items_url, follow_redirects=True)
90
98
  if items_resp.status_code != 200:
91
99
  raise RuntimeError(
@@ -94,7 +102,15 @@ class DatalabClient(BaseDatalabClient):
94
102
  items = items_resp.json()
95
103
  if items["status"] != "success":
96
104
  raise RuntimeError(f"Failed to list items at {items_url}: {items['status']!r}.")
97
- return items[item_type]
105
+
106
+ if item_type in items:
107
+ # Old approach
108
+ return items[item_type]
109
+ if "items" in items:
110
+ return items["items"]
111
+
112
+ else:
113
+ return items
98
114
 
99
115
  def search_items(
100
116
  self, query: str, item_types: Iterable[str] | str = ("samples", "cells")
@@ -153,10 +169,10 @@ class DatalabClient(BaseDatalabClient):
153
169
 
154
170
  if collection_id is not None:
155
171
  try:
156
- collection_immutable_id = self.get_collection(collection_id)["immutable_id"]
172
+ collection_immutable_id = self.get_collection(collection_id)[0]["immutable_id"]
157
173
  except RuntimeError:
158
174
  self.create_collection(collection_id)
159
- collection_immutable_id = self.get_collection(collection_id)["immutable_id"]
175
+ collection_immutable_id = self.get_collection(collection_id)[0]["immutable_id"]
160
176
  new_item["collections"] = new_item.get("collections", [])
161
177
  new_item["collections"].append({"immutable_id": collection_immutable_id})
162
178
 
@@ -173,6 +189,10 @@ class DatalabClient(BaseDatalabClient):
173
189
  f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
174
190
  )
175
191
  if created_item["status"] != "success":
192
+ if "DuplicateKeyError" in created_item["message"]:
193
+ raise DuplicateItemError(
194
+ f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
195
+ )
176
196
  raise RuntimeError(f"Failed to create item at {create_item_url}: {created_item}.")
177
197
  return created_item["sample_list_entry"]
178
198
 
@@ -468,14 +488,15 @@ class DatalabClient(BaseDatalabClient):
468
488
 
469
489
  return resp.json()["new_block_data"]
470
490
 
471
- def get_collection(self, collection_id: str) -> dict[str, Any]:
491
+ def get_collection(self, collection_id: str) -> tuple[dict[str, Any], list[dict[str, Any]]]:
472
492
  """Get a collection with a given ID.
473
493
 
474
494
  Parameters:
475
495
  collection_id: The ID of the collection to search for.
476
496
 
477
497
  Returns:
478
- A dictionary of collection data for the collection with the given ID.
498
+ A dictionary of collection data for the collection with the given ID,
499
+ and a list of the member items.
479
500
 
480
501
  """
481
502
  collection_url = f"{self.datalab_api_url}/collections/{collection_id}"
@@ -489,7 +510,7 @@ class DatalabClient(BaseDatalabClient):
489
510
  raise RuntimeError(
490
511
  f"Failed to get collection at {collection_url}: {collection['status']!r}."
491
512
  )
492
- return collection["data"]
513
+ return collection["data"], collection["child_items"]
493
514
 
494
515
  def create_collection(
495
516
  self, collection_id: str, collection_data: dict | None = None
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datalab-api
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: A Python API for instances of the datalab data management platform (https://github.com/datalab-org/datalab).
5
5
  Author-email: Matthew Evans <matthew@ml-evs.science>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: homepage, https://github.com/datalab-org/datalab-api
8
8
  Project-URL: repository, https://github.com/datalab-org/datalab-api
9
9
  Project-URL: documentation, https://datalab-python-api.readthedocs.io
@@ -55,3 +55,27 @@ def test_sample_list(fake_samples_json, fake_info_json, fake_sample_json, fake_b
55
55
  sample = client.get_item("KUVEKJ", display=True)
56
56
  assert fake_item_api.called
57
57
  assert sample["item_id"] == "KUVEKJ"
58
+
59
+
60
+ @respx.mock
61
+ def test_collection_get(fake_info_json, fake_block_info_json, fake_collection_json):
62
+ fake_api = respx.get("https://api.datalab.industries/").mock(
63
+ return_value=Response(200, content="<!doctype html></html>")
64
+ )
65
+ fake_info_api = respx.get("https://api.datalab.industries/info").mock(
66
+ return_value=Response(200, json=fake_info_json)
67
+ )
68
+ fake_block_info_api = respx.get("https://api.datalab.industries/info/blocks").mock(
69
+ return_value=Response(200, json=fake_block_info_json)
70
+ )
71
+
72
+ fake_collection_api = respx.get(
73
+ "https://api.datalab.industries/collections/test_collection"
74
+ ).mock(return_value=Response(200, json=fake_collection_json))
75
+
76
+ with DatalabClient("https://api.datalab.industries") as client:
77
+ collection, children = client.get_collection("test_collection")
78
+ assert fake_api.called
79
+ assert fake_info_api.called
80
+ assert fake_block_info_api.called
81
+ assert fake_collection_api.called
File without changes
File without changes
File without changes