mpcontribs-client 5.10.1__tar.gz → 5.10.3__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.
Files changed (19) hide show
  1. {mpcontribs_client-5.10.1/mpcontribs_client.egg-info → mpcontribs_client-5.10.3}/PKG-INFO +3 -2
  2. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs/client/__init__.py +92 -86
  3. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3/mpcontribs_client.egg-info}/PKG-INFO +3 -2
  4. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs_client.egg-info/SOURCES.txt +2 -2
  5. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/requirements/deployment.txt +55 -46
  6. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/requirements/ubuntu-latest_py3.11.txt +56 -47
  7. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/requirements/ubuntu-latest_py3.11_extras.txt +70 -60
  8. mpcontribs_client-5.10.1/requirements/ubuntu-latest_py3.10.txt → mpcontribs_client-5.10.3/requirements/ubuntu-latest_py3.12.txt +58 -52
  9. mpcontribs_client-5.10.1/requirements/ubuntu-latest_py3.10_extras.txt → mpcontribs_client-5.10.3/requirements/ubuntu-latest_py3.12_extras.txt +72 -71
  10. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/LICENSE +0 -0
  11. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/README.md +0 -0
  12. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs_client.egg-info/dependency_links.txt +0 -0
  13. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs_client.egg-info/not-zip-safe +0 -0
  14. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs_client.egg-info/requires.txt +0 -0
  15. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/mpcontribs_client.egg-info/top_level.txt +0 -0
  16. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/setup.cfg +0 -0
  17. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/setup.py +0 -0
  18. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/tests/conftest.py +0 -0
  19. {mpcontribs_client-5.10.1 → mpcontribs_client-5.10.3}/tests/test_client.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: mpcontribs-client
3
- Version: 5.10.1
3
+ Version: 5.10.3
4
4
  Summary: client library for MPContribs API
5
5
  Home-page: https://github.com/materialsproject/MPContribs/tree/master/mpcontribs-client
6
6
  Author: Patrick Huck
@@ -41,6 +41,7 @@ Dynamic: description
41
41
  Dynamic: description-content-type
42
42
  Dynamic: home-page
43
43
  Dynamic: license
44
+ Dynamic: license-file
44
45
  Dynamic: provides-extra
45
46
  Dynamic: requires-dist
46
47
  Dynamic: requires-python
@@ -20,7 +20,7 @@ from math import isclose
20
20
  from semantic_version import Version
21
21
  from requests.exceptions import RequestException
22
22
  from bson.objectid import ObjectId
23
- from typing import Union, Type, List
23
+ from typing import Union, Type, Optional
24
24
  from tqdm.auto import tqdm
25
25
  from hashlib import md5
26
26
  from pathlib import Path
@@ -297,7 +297,7 @@ def _response_hook(resp, *args, **kwargs):
297
297
  def _chunk_by_size(items, max_size=0.95 * MAX_BYTES):
298
298
  buffer, buffer_size = [], 0
299
299
 
300
- for idx, item in enumerate(items):
300
+ for item in items:
301
301
  item_size = _compress(item)[0]
302
302
 
303
303
  if buffer_size + item_size <= max_size:
@@ -466,7 +466,7 @@ class Structure(PmgStructure):
466
466
  class Attachment(dict):
467
467
  """Wrapper class around dict to handle attachments"""
468
468
 
469
- def decode(self) -> str:
469
+ def decode(self) -> bytes:
470
470
  """Decode base64-encoded content of attachment"""
471
471
  return b64decode(self["content"], validate=True)
472
472
 
@@ -478,7 +478,7 @@ class Attachment(dict):
478
478
 
479
479
  return unpacked
480
480
 
481
- def write(self, outdir: Union[str, Path] = None) -> Path:
481
+ def write(self, outdir: Optional[Union[str, Path]] = None) -> Path:
482
482
  """Write attachment to file using its name
483
483
 
484
484
  Args:
@@ -490,7 +490,7 @@ class Attachment(dict):
490
490
  path.write_bytes(content)
491
491
  return path
492
492
 
493
- def display(self, outdir: Union[str, Path] = None):
493
+ def display(self, outdir: Optional[Union[str, Path]] = None):
494
494
  """Display Image/FileLink for attachment if in IPython/Jupyter
495
495
 
496
496
  Args:
@@ -761,7 +761,7 @@ def _expand_params(protocol, host, version, projects_json, apikey=None):
761
761
  columns = {"string": [], "number": []}
762
762
  projects = ujson.loads(projects_json)
763
763
  query = {"project__in": ",".join(projects)}
764
- query["_fields"] = ["columns"]
764
+ query["_fields"] = "columns"
765
765
  url = f"{protocol}://{host}"
766
766
  http_client = RequestsClient()
767
767
  http_client.session.headers["Content-Type"] = "application/json"
@@ -870,11 +870,11 @@ class Client(SwaggerClient):
870
870
 
871
871
  def __init__(
872
872
  self,
873
- apikey: str = None,
874
- headers: dict = None,
875
- host: str = None,
876
- project: str = None,
877
- session: requests.Session = None,
873
+ apikey: Optional[str] = None,
874
+ headers: Optional[dict] = None,
875
+ host: Optional[str] = None,
876
+ project: Optional[str] = None,
877
+ session: Optional[requests.Session] = None,
878
878
  ):
879
879
  """Initialize the client - only reloads API spec from server as needed
880
880
 
@@ -966,7 +966,7 @@ class Client(SwaggerClient):
966
966
 
967
967
  def _get_per_page_default_max(
968
968
  self, op: str = "query", resource: str = "contributions"
969
- ) -> int:
969
+ ) -> tuple[int, int]:
970
970
  attr = f"{op}{resource.capitalize()}"
971
971
  resource = self.swagger_spec.resources[resource]
972
972
  param_spec = getattr(resource, attr).params["per_page"].param_spec
@@ -988,7 +988,7 @@ class Client(SwaggerClient):
988
988
  op: str = "query",
989
989
  resource: str = "contributions",
990
990
  pages: int = -1,
991
- ) -> List[dict]:
991
+ ) -> list[dict]:
992
992
  """Avoid URI too long errors"""
993
993
  pp_default, pp_max = self._get_per_page_default_max(op=op, resource=resource)
994
994
  per_page = (
@@ -1047,7 +1047,7 @@ class Client(SwaggerClient):
1047
1047
  params: dict,
1048
1048
  rel_url: str = "contributions",
1049
1049
  op: str = "query",
1050
- data: dict = None,
1050
+ data: Optional[dict] = None,
1051
1051
  ):
1052
1052
  rname = rel_url.split("/", 1)[0]
1053
1053
  resource = self.swagger_spec.resources[rname]
@@ -1065,7 +1065,9 @@ class Client(SwaggerClient):
1065
1065
  return future
1066
1066
 
1067
1067
  def available_query_params(
1068
- self, startswith: tuple = None, resource: str = "contributions"
1068
+ self,
1069
+ startswith: Optional[tuple] = None,
1070
+ resource: str = "contributions",
1069
1071
  ) -> list:
1070
1072
  resources = self.swagger_spec.resources
1071
1073
  resource_obj = resources.get(resource)
@@ -1081,7 +1083,9 @@ class Client(SwaggerClient):
1081
1083
 
1082
1084
  return [param for param in params if param.startswith(startswith)]
1083
1085
 
1084
- def get_project(self, name: str = None, fields: list = None) -> Type[Dict]:
1086
+ def get_project(
1087
+ self, name: Optional[str] = None, fields: Optional[list] = None
1088
+ ) -> Dict:
1085
1089
  """Retrieve a project entry
1086
1090
 
1087
1091
  Args:
@@ -1099,12 +1103,12 @@ class Client(SwaggerClient):
1099
1103
 
1100
1104
  def query_projects(
1101
1105
  self,
1102
- query: dict = None,
1103
- term: str = None,
1104
- fields: list = None,
1105
- sort: str = None,
1106
+ query: Optional[dict] = None,
1107
+ term: Optional[str] = None,
1108
+ fields: Optional[list] = None,
1109
+ sort: Optional[str] = None,
1106
1110
  timeout: int = -1,
1107
- ) -> List[dict]:
1111
+ ) -> list[dict]:
1108
1112
  """Query projects by query and/or term (Atlas Search)
1109
1113
 
1110
1114
  See `client.available_query_params(resource="projects")` for keyword arguments used in
@@ -1206,7 +1210,7 @@ class Client(SwaggerClient):
1206
1210
  else:
1207
1211
  raise MPContribsClientError(resp)
1208
1212
 
1209
- def update_project(self, update: dict, name: str = None):
1213
+ def update_project(self, update: dict, name: Optional[str] = None):
1210
1214
  """Update project info
1211
1215
 
1212
1216
  Args:
@@ -1272,7 +1276,7 @@ class Client(SwaggerClient):
1272
1276
  else:
1273
1277
  raise MPContribsClientError(error)
1274
1278
 
1275
- def delete_project(self, name: str = None):
1279
+ def delete_project(self, name: Optional[str] = None):
1276
1280
  """Delete a project
1277
1281
 
1278
1282
  Args:
@@ -1291,7 +1295,7 @@ class Client(SwaggerClient):
1291
1295
  if resp and "error" in resp:
1292
1296
  raise MPContribsClientError(resp["error"])
1293
1297
 
1294
- def get_contribution(self, cid: str, fields: list = None) -> Type[Dict]:
1298
+ def get_contribution(self, cid: str, fields: Optional[list] = None) -> Dict:
1295
1299
  """Retrieve a contribution
1296
1300
 
1297
1301
  Args:
@@ -1305,7 +1309,7 @@ class Client(SwaggerClient):
1305
1309
  self.contributions.getContributionById(pk=cid, _fields=fields).result()
1306
1310
  )
1307
1311
 
1308
- def get_table(self, tid_or_md5: str) -> Type[Table]:
1312
+ def get_table(self, tid_or_md5: str) -> Table:
1309
1313
  """Retrieve full Pandas DataFrame for a table
1310
1314
 
1311
1315
  Args:
@@ -1347,7 +1351,7 @@ class Client(SwaggerClient):
1347
1351
 
1348
1352
  return Table.from_dict(table)
1349
1353
 
1350
- def get_structure(self, sid_or_md5: str) -> Type[Structure]:
1354
+ def get_structure(self, sid_or_md5: str) -> Structure:
1351
1355
  """Retrieve pymatgen structure
1352
1356
 
1353
1357
  Args:
@@ -1375,7 +1379,7 @@ class Client(SwaggerClient):
1375
1379
  resp = self.structures.getStructureById(pk=sid, _fields=fields).result()
1376
1380
  return Structure.from_dict(resp)
1377
1381
 
1378
- def get_attachment(self, aid_or_md5: str) -> Type[Attachment]:
1382
+ def get_attachment(self, aid_or_md5: str) -> Attachment:
1379
1383
  """Retrieve an attachment
1380
1384
 
1381
1385
  Args:
@@ -1403,7 +1407,9 @@ class Client(SwaggerClient):
1403
1407
  self.attachments.getAttachmentById(pk=aid, _fields=["_all"]).result()
1404
1408
  )
1405
1409
 
1406
- def init_columns(self, columns: dict = None, name: str = None) -> dict:
1410
+ def init_columns(
1411
+ self, columns: Optional[dict] = None, name: Optional[str] = None
1412
+ ) -> dict:
1407
1413
  """initialize columns for a project to set their order and desired units
1408
1414
 
1409
1415
  The `columns` field of a project tracks the minima and maxima of each `data` field
@@ -1560,7 +1566,7 @@ class Client(SwaggerClient):
1560
1566
 
1561
1567
  return self.projects.updateProjectByName(pk=name, project=payload).result()
1562
1568
 
1563
- def delete_contributions(self, query: dict = None, timeout: int = -1):
1569
+ def delete_contributions(self, query: Optional[dict] = None, timeout: int = -1):
1564
1570
  """Remove all contributions for a query
1565
1571
 
1566
1572
  Args:
@@ -1578,12 +1584,11 @@ class Client(SwaggerClient):
1578
1584
  if self.project:
1579
1585
  query["project"] = self.project
1580
1586
 
1581
- cids = list(self.get_all_ids(query).get(query["project"], {}).get("ids", set()))
1587
+ name = query["project"]
1588
+ cids = list(self.get_all_ids(query).get(name, {}).get("ids", set()))
1582
1589
 
1583
1590
  if not cids:
1584
- logger.info(
1585
- f"There aren't any contributions to delete for {query['project']}"
1586
- )
1591
+ logger.info(f"There aren't any contributions to delete for {name}")
1587
1592
  return
1588
1593
 
1589
1594
  total = len(cids)
@@ -1594,7 +1599,7 @@ class Client(SwaggerClient):
1594
1599
  _run_futures(futures, total=total, timeout=timeout)
1595
1600
  left, _ = self.get_totals(query=query)
1596
1601
  deleted = total - left
1597
- self.init_columns()
1602
+ self.init_columns(name=name)
1598
1603
  self._reinit()
1599
1604
  toc = time.perf_counter()
1600
1605
  dt = (toc - tic) / 60
@@ -1607,7 +1612,7 @@ class Client(SwaggerClient):
1607
1612
 
1608
1613
  def get_totals(
1609
1614
  self,
1610
- query: dict = None,
1615
+ query: Optional[dict] = None,
1611
1616
  timeout: int = -1,
1612
1617
  resource: str = "contributions",
1613
1618
  op: str = "query",
@@ -1648,11 +1653,11 @@ class Client(SwaggerClient):
1648
1653
 
1649
1654
  return result["total_count"], result["total_pages"]
1650
1655
 
1651
- def count(self, query: dict = None) -> int:
1656
+ def count(self, query: Optional[dict] = None) -> int:
1652
1657
  """shortcut for get_totals()"""
1653
1658
  return self.get_totals(query=query)[0]
1654
1659
 
1655
- def get_unique_identifiers_flags(self, query: dict = None) -> dict:
1660
+ def get_unique_identifiers_flags(self, query: Optional[dict] = None) -> dict:
1656
1661
  """Retrieve values for `unique_identifiers` flags.
1657
1662
 
1658
1663
  See `client.available_query_params(resource="projects")` for available query parameters.
@@ -1672,10 +1677,10 @@ class Client(SwaggerClient):
1672
1677
 
1673
1678
  def get_all_ids(
1674
1679
  self,
1675
- query: dict = None,
1676
- include: List[str] = None,
1680
+ query: Optional[dict] = None,
1681
+ include: Optional[list[str]] = None,
1677
1682
  timeout: int = -1,
1678
- data_id_fields: dict = None,
1683
+ data_id_fields: Optional[dict] = None,
1679
1684
  fmt: str = "sets",
1680
1685
  op: str = "query",
1681
1686
  ) -> dict:
@@ -1830,12 +1835,12 @@ class Client(SwaggerClient):
1830
1835
 
1831
1836
  def query_contributions(
1832
1837
  self,
1833
- query: dict = None,
1834
- fields: list = None,
1835
- sort: str = None,
1838
+ query: Optional[dict] = None,
1839
+ fields: Optional[list] = None,
1840
+ sort: Optional[str] = None,
1836
1841
  paginate: bool = False,
1837
1842
  timeout: int = -1,
1838
- ) -> List[dict]:
1843
+ ) -> dict:
1839
1844
  """Query contributions
1840
1845
 
1841
1846
  See `client.available_query_params()` for keyword arguments used in query.
@@ -1886,7 +1891,7 @@ class Client(SwaggerClient):
1886
1891
  return ret
1887
1892
 
1888
1893
  def update_contributions(
1889
- self, data: dict, query: dict = None, timeout: int = -1
1894
+ self, data: dict, query: Optional[dict] = None, timeout: int = -1
1890
1895
  ) -> dict:
1891
1896
  """Apply the same update to all contributions in a project (matching query)
1892
1897
 
@@ -1898,7 +1903,7 @@ class Client(SwaggerClient):
1898
1903
  timeout (int): cancel remaining requests if timeout exceeded (in seconds)
1899
1904
  """
1900
1905
  if not data:
1901
- return "Nothing to update."
1906
+ raise MPContribsClientError("Nothing to update.")
1902
1907
 
1903
1908
  tic = time.perf_counter()
1904
1909
  valid, error = self._is_valid_payload("Contribution", data)
@@ -1912,27 +1917,28 @@ class Client(SwaggerClient):
1912
1917
 
1913
1918
  query = query or {}
1914
1919
 
1915
- if not self.project and (not query or "project" not in query):
1916
- raise MPContribsClientError(
1917
- "initialize client with project, or include project in query!"
1918
- )
1919
-
1920
- if "project" in query and self.project != query["project"]:
1921
- raise MPContribsClientError(
1922
- f"client initialized with different project {self.project}!"
1923
- )
1920
+ if self.project:
1921
+ if "project" in query and self.project != query["project"]:
1922
+ raise MPContribsClientError(
1923
+ f"client initialized with different project {self.project}!"
1924
+ )
1925
+ query["project"] = self.project
1926
+ else:
1927
+ if not query or "project" not in query:
1928
+ raise MPContribsClientError(
1929
+ "initialize client with project, or include project in query!"
1930
+ )
1924
1931
 
1925
- query["project"] = self.project
1926
- cids = list(self.get_all_ids(query).get(self.project, {}).get("ids", set()))
1932
+ name = query["project"]
1933
+ cids = list(self.get_all_ids(query).get(name, {}).get("ids", set()))
1927
1934
 
1928
1935
  if not cids:
1929
- logger.info(f"There aren't any contributions to update for {self.project}")
1930
- return
1936
+ raise MPContribsClientError(
1937
+ f"There aren't any contributions to update for {name}"
1938
+ )
1931
1939
 
1932
1940
  # get current list of data columns to decide if swagger reload is needed
1933
- resp = self.projects.getProjectByName(
1934
- pk=self.project, _fields=["columns"]
1935
- ).result()
1941
+ resp = self.projects.getProjectByName(pk=name, _fields=["columns"]).result()
1936
1942
  old_paths = set(c["path"] for c in resp["columns"])
1937
1943
 
1938
1944
  total = len(cids)
@@ -1947,20 +1953,18 @@ class Client(SwaggerClient):
1947
1953
  updated = sum(resp["count"] for _, resp in responses.items())
1948
1954
 
1949
1955
  if updated:
1950
- resp = self.projects.getProjectByName(
1951
- pk=self.project, _fields=["columns"]
1952
- ).result()
1956
+ resp = self.projects.getProjectByName(pk=name, _fields=["columns"]).result()
1953
1957
  new_paths = set(c["path"] for c in resp["columns"])
1954
1958
 
1955
1959
  if new_paths != old_paths:
1956
- self.init_columns()
1960
+ self.init_columns(name=name)
1957
1961
  self._reinit()
1958
1962
 
1959
1963
  toc = time.perf_counter()
1960
1964
  return {"updated": updated, "total": total, "seconds_elapsed": toc - tic}
1961
1965
 
1962
1966
  def make_public(
1963
- self, query: dict = None, recursive: bool = False, timeout: int = -1
1967
+ self, query: Optional[dict] = None, recursive: bool = False, timeout: int = -1
1964
1968
  ) -> dict:
1965
1969
  """Publish a project and optionally its contributions
1966
1970
 
@@ -1973,7 +1977,7 @@ class Client(SwaggerClient):
1973
1977
  )
1974
1978
 
1975
1979
  def make_private(
1976
- self, query: dict = None, recursive: bool = False, timeout: int = -1
1980
+ self, query: Optional[dict] = None, recursive: bool = False, timeout: int = -1
1977
1981
  ) -> dict:
1978
1982
  """Make a project and optionally its contributions private
1979
1983
 
@@ -1988,7 +1992,7 @@ class Client(SwaggerClient):
1988
1992
  def _set_is_public(
1989
1993
  self,
1990
1994
  is_public: bool,
1991
- query: dict = None,
1995
+ query: Optional[dict] = None,
1992
1996
  recursive: bool = False,
1993
1997
  timeout: int = -1,
1994
1998
  ) -> dict:
@@ -2040,7 +2044,7 @@ class Client(SwaggerClient):
2040
2044
  if recursive:
2041
2045
  query = query or {}
2042
2046
  query["is_public"] = not is_public
2043
- ret["contributions"] = self.updateContributions(
2047
+ ret["contributions"] = self.update_contributions(
2044
2048
  {"is_public": is_public}, query=query, timeout=timeout
2045
2049
  )
2046
2050
 
@@ -2048,7 +2052,7 @@ class Client(SwaggerClient):
2048
2052
 
2049
2053
  def submit_contributions(
2050
2054
  self,
2051
- contributions: List[dict],
2055
+ contributions: list[dict],
2052
2056
  ignore_dupes: bool = False,
2053
2057
  timeout: int = -1,
2054
2058
  skip_dupe_check: bool = False,
@@ -2250,6 +2254,8 @@ class Client(SwaggerClient):
2250
2254
  element = Attachment.from_file(element)
2251
2255
 
2252
2256
  dct = {k: element[k] for k in ["mime", "content"]}
2257
+ else:
2258
+ raise MPContribsClientError("This should never happen")
2253
2259
 
2254
2260
  digest = get_md5(dct)
2255
2261
 
@@ -2406,11 +2412,11 @@ class Client(SwaggerClient):
2406
2412
  logger.info(
2407
2413
  f"{project_name}: resubmit failed contributions manually"
2408
2414
  )
2415
+ self.init_columns(name=project_name)
2409
2416
 
2417
+ self._reinit()
2410
2418
  toc = time.perf_counter()
2411
2419
  dt = (toc - tic) / 60
2412
- self.init_columns()
2413
- self._reinit()
2414
2420
  logger.info(
2415
2421
  f"It took {dt:.1f}min to submit {total_processed}/{total} contributions."
2416
2422
  )
@@ -2419,12 +2425,12 @@ class Client(SwaggerClient):
2419
2425
 
2420
2426
  def download_contributions(
2421
2427
  self,
2422
- query: dict = None,
2428
+ query: Optional[dict] = None,
2423
2429
  outdir: Union[str, Path] = DEFAULT_DOWNLOAD_DIR,
2424
2430
  overwrite: bool = False,
2425
- include: List[str] = None,
2431
+ include: Optional[list[str]] = None,
2426
2432
  timeout: int = -1,
2427
- ) -> int:
2433
+ ) -> list:
2428
2434
  """Download a list of contributions as .json.gz file(s)
2429
2435
 
2430
2436
  Args:
@@ -2446,7 +2452,7 @@ class Client(SwaggerClient):
2446
2452
  if include and not components:
2447
2453
  raise MPContribsClientError(f"`include` must be subset of {COMPONENTS}!")
2448
2454
 
2449
- all_ids = self.get_all_ids(query, include=components, timeout=timeout)
2455
+ all_ids = self.get_all_ids(query, include=list(components), timeout=timeout)
2450
2456
  fmt = query.get("format", "json")
2451
2457
  contributions, components_loaded = [], defaultdict(dict)
2452
2458
 
@@ -2520,12 +2526,12 @@ class Client(SwaggerClient):
2520
2526
 
2521
2527
  def download_structures(
2522
2528
  self,
2523
- ids: List[str],
2529
+ ids: list[str],
2524
2530
  outdir: Union[str, Path] = DEFAULT_DOWNLOAD_DIR,
2525
2531
  overwrite: bool = False,
2526
2532
  timeout: int = -1,
2527
2533
  fmt: str = "json",
2528
- ) -> Path:
2534
+ ) -> list[Path]:
2529
2535
  """Download a list of structures as a .json.gz file
2530
2536
 
2531
2537
  Args:
@@ -2549,12 +2555,12 @@ class Client(SwaggerClient):
2549
2555
 
2550
2556
  def download_tables(
2551
2557
  self,
2552
- ids: List[str],
2558
+ ids: list[str],
2553
2559
  outdir: Union[str, Path] = DEFAULT_DOWNLOAD_DIR,
2554
2560
  overwrite: bool = False,
2555
2561
  timeout: int = -1,
2556
2562
  fmt: str = "json",
2557
- ) -> Path:
2563
+ ) -> list[Path]:
2558
2564
  """Download a list of tables as a .json.gz file
2559
2565
 
2560
2566
  Args:
@@ -2578,12 +2584,12 @@ class Client(SwaggerClient):
2578
2584
 
2579
2585
  def download_attachments(
2580
2586
  self,
2581
- ids: List[str],
2587
+ ids: list[str],
2582
2588
  outdir: Union[str, Path] = DEFAULT_DOWNLOAD_DIR,
2583
2589
  overwrite: bool = False,
2584
2590
  timeout: int = -1,
2585
2591
  fmt: str = "json",
2586
- ) -> Path:
2592
+ ) -> list[Path]:
2587
2593
  """Download a list of attachments as a .json.gz file
2588
2594
 
2589
2595
  Args:
@@ -2608,12 +2614,12 @@ class Client(SwaggerClient):
2608
2614
  def _download_resource(
2609
2615
  self,
2610
2616
  resource: str,
2611
- ids: List[str],
2617
+ ids: list[str],
2612
2618
  outdir: Union[str, Path] = DEFAULT_DOWNLOAD_DIR,
2613
2619
  overwrite: bool = False,
2614
2620
  timeout: int = -1,
2615
2621
  fmt: str = "json",
2616
- ) -> Path:
2622
+ ) -> list[Path]:
2617
2623
  """Helper to download a list of resources as .json.gz file
2618
2624
 
2619
2625
  Args:
@@ -2625,7 +2631,7 @@ class Client(SwaggerClient):
2625
2631
  fmt: download format - "json" or "csv"
2626
2632
 
2627
2633
  Returns:
2628
- tuple (paths of output files, objects per path / per_page)
2634
+ list of paths to output files
2629
2635
  """
2630
2636
  resources = ["contributions"] + COMPONENTS
2631
2637
  if resource not in resources:
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: mpcontribs-client
3
- Version: 5.10.1
3
+ Version: 5.10.3
4
4
  Summary: client library for MPContribs API
5
5
  Home-page: https://github.com/materialsproject/MPContribs/tree/master/mpcontribs-client
6
6
  Author: Patrick Huck
@@ -41,6 +41,7 @@ Dynamic: description
41
41
  Dynamic: description-content-type
42
42
  Dynamic: home-page
43
43
  Dynamic: license
44
+ Dynamic: license-file
44
45
  Dynamic: provides-extra
45
46
  Dynamic: requires-dist
46
47
  Dynamic: requires-python
@@ -9,9 +9,9 @@ mpcontribs_client.egg-info/not-zip-safe
9
9
  mpcontribs_client.egg-info/requires.txt
10
10
  mpcontribs_client.egg-info/top_level.txt
11
11
  requirements/deployment.txt
12
- requirements/ubuntu-latest_py3.10.txt
13
- requirements/ubuntu-latest_py3.10_extras.txt
14
12
  requirements/ubuntu-latest_py3.11.txt
15
13
  requirements/ubuntu-latest_py3.11_extras.txt
14
+ requirements/ubuntu-latest_py3.12.txt
15
+ requirements/ubuntu-latest_py3.12_extras.txt
16
16
  tests/conftest.py
17
17
  tests/test_client.py