datalab-api 0.2.9__tar.gz → 0.2.11__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,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: datalab-api
3
- Version: 0.2.9
3
+ Version: 0.2.11
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
6
  License: MIT
@@ -43,6 +43,7 @@ Requires-Dist: pandas~=2.2; extra == "cheminventory-helper"
43
43
  Requires-Dist: openpyxl~=3.0; extra == "cheminventory-helper"
44
44
  Provides-Extra: all
45
45
  Requires-Dist: datalab-api[cli,dev,docs]; extra == "all"
46
+ Dynamic: license-file
46
47
 
47
48
  # <div align="center"><i>datalab</i> Python API</div>
48
49
 
@@ -153,10 +153,10 @@ class DatalabClient(BaseDatalabClient):
153
153
 
154
154
  if collection_id is not None:
155
155
  try:
156
- collection_immutable_id = self.get_collection(collection_id)["immutable_id"]
156
+ collection_immutable_id = self.get_collection(collection_id)[0]["immutable_id"]
157
157
  except RuntimeError:
158
158
  self.create_collection(collection_id)
159
- collection_immutable_id = self.get_collection(collection_id)["immutable_id"]
159
+ collection_immutable_id = self.get_collection(collection_id)[0]["immutable_id"]
160
160
  new_item["collections"] = new_item.get("collections", [])
161
161
  new_item["collections"].append({"immutable_id": collection_immutable_id})
162
162
 
@@ -173,6 +173,10 @@ class DatalabClient(BaseDatalabClient):
173
173
  f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
174
174
  )
175
175
  if created_item["status"] != "success":
176
+ if "DuplicateKeyError" in created_item["message"]:
177
+ raise DuplicateItemError(
178
+ f"Item {item_id=} already exists at {create_item_url}: {created_item['status']!r}."
179
+ )
176
180
  raise RuntimeError(f"Failed to create item at {create_item_url}: {created_item}.")
177
181
  return created_item["sample_list_entry"]
178
182
 
@@ -282,8 +286,9 @@ class DatalabClient(BaseDatalabClient):
282
286
  warnings.warn(f"Will not overwrite existing file {f['name']}")
283
287
  continue
284
288
  with open(f["name"], "wb") as file:
285
- response = self.session.get(url, follow_redirects=True)
286
- file.write(response.content)
289
+ with self.session.stream("GET", url, follow_redirects=True) as response:
290
+ for chunk in response.iter_bytes(chunk_size=1024):
291
+ file.write(chunk)
287
292
 
288
293
  def get_block(self, item_id: str, block_id: str, block_data: dict[str, Any]) -> dict[str, Any]:
289
294
  """Get a block with a given ID and block data.
@@ -467,14 +472,15 @@ class DatalabClient(BaseDatalabClient):
467
472
 
468
473
  return resp.json()["new_block_data"]
469
474
 
470
- def get_collection(self, collection_id: str) -> dict[str, Any]:
475
+ def get_collection(self, collection_id: str) -> tuple[dict[str, Any], list[dict[str, Any]]]:
471
476
  """Get a collection with a given ID.
472
477
 
473
478
  Parameters:
474
479
  collection_id: The ID of the collection to search for.
475
480
 
476
481
  Returns:
477
- A dictionary of collection data for the collection with the given ID.
482
+ A dictionary of collection data for the collection with the given ID,
483
+ and a list of the member items.
478
484
 
479
485
  """
480
486
  collection_url = f"{self.datalab_api_url}/collections/{collection_id}"
@@ -488,7 +494,7 @@ class DatalabClient(BaseDatalabClient):
488
494
  raise RuntimeError(
489
495
  f"Failed to get collection at {collection_url}: {collection['status']!r}."
490
496
  )
491
- return collection["data"]
497
+ return collection["data"], collection["child_items"]
492
498
 
493
499
  def create_collection(
494
500
  self, collection_id: str, collection_data: dict | None = None
@@ -270,7 +270,7 @@ class BaseDatalabClient(metaclass=AutoPrettyPrint):
270
270
 
271
271
  return self.api_key
272
272
 
273
- def __enter__(self) -> "BaseDatalabClient":
273
+ def __enter__(self):
274
274
  return self
275
275
 
276
276
  def __exit__(self, *_):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: datalab-api
3
- Version: 0.2.9
3
+ Version: 0.2.11
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
6
  License: MIT
@@ -43,6 +43,7 @@ Requires-Dist: pandas~=2.2; extra == "cheminventory-helper"
43
43
  Requires-Dist: openpyxl~=3.0; extra == "cheminventory-helper"
44
44
  Provides-Extra: all
45
45
  Requires-Dist: datalab-api[cli,dev,docs]; extra == "all"
46
+ Dynamic: license-file
46
47
 
47
48
  # <div align="center"><i>datalab</i> Python API</div>
48
49
 
@@ -28,7 +28,7 @@ def test_redirect_url(fake_ui_html, fake_info_json, fake_block_info_json):
28
28
 
29
29
 
30
30
  @respx.mock
31
- def test_sample_list(fake_samples_json, fake_info_json, fake_block_info_json):
31
+ def test_sample_list(fake_samples_json, fake_info_json, fake_sample_json, fake_block_info_json):
32
32
  fake_api = respx.get("https://api.datalab.industries/").mock(
33
33
  return_value=Response(200, content="<!doctype html></html>")
34
34
  )
@@ -41,6 +41,9 @@ def test_sample_list(fake_samples_json, fake_info_json, fake_block_info_json):
41
41
  fake_block_info_api = respx.get("https://api.datalab.industries/info/blocks").mock(
42
42
  return_value=Response(200, json=fake_block_info_json)
43
43
  )
44
+ fake_item_api = respx.get("https://api.datalab.industries/get-item-data/KUVEKJ").mock(
45
+ return_value=Response(200, json=fake_sample_json)
46
+ )
44
47
  with DatalabClient("https://api.datalab.industries") as client:
45
48
  samples = client.get_items(display=True)
46
49
  assert fake_samples_api.called
@@ -49,3 +52,30 @@ def test_sample_list(fake_samples_json, fake_info_json, fake_block_info_json):
49
52
  assert fake_block_info_api.called
50
53
  assert len(samples)
51
54
  assert samples[0]["item_id"] == "test"
55
+ sample = client.get_item("KUVEKJ", display=True)
56
+ assert fake_item_api.called
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
File without changes