Skip to content

Commit c607814

Browse files
temporarily reorganize symmetry query around splitting into separate query chunks
1 parent 4c82145 commit c607814

2 files changed

Lines changed: 35 additions & 12 deletions

File tree

mp_api/client/core/client.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def _query_resource(
659659
use_document_model: if None, will defer to the self.use_document_model attribute
660660
num_chunks: Maximum number of chunks of data to yield. None will yield all possible.
661661
chunk_size: Number of data entries per chunk.
662-
timeout : Time in seconds to wait until a request timeout error is thrown
662+
timeout (float or None): Time in seconds to wait until a request timeout error is thrown
663663
664664
Returns:
665665
A Resource, a dict with two keys, "data" containing a list of documents, and
@@ -810,9 +810,9 @@ def _submit_requests(
810810
url: str,
811811
criteria: dict[str, Any],
812812
use_document_model: bool,
813-
chunk_size: int,
813+
chunk_size: int | None,
814814
num_chunks: int | None = None,
815-
timeout: float | None = None,
815+
timeout: int | None = None,
816816
max_batch_size: int = 100,
817817
norecur: bool = False,
818818
) -> dict:
@@ -826,8 +826,8 @@ def _submit_requests(
826826
criteria (dict of str): dictionary of criteria to filter down
827827
use_document_model (bool): whether to use the document model
828828
num_chunks (int or None): Maximum number of chunks of data to yield. None will yield all possible.
829-
chunk_size (int): Number of data entries per chunk.
830-
timeout (float): Time in seconds to wait until a request timeout error is thrown
829+
chunk_size (int or None): Number of data entries per chunk.
830+
timeout (int or None): Time in seconds to wait until a request timeout error is thrown
831831
max_batch_size (int) : Maximum size of a batch when retrieving batches in parallel
832832
norecur (bool) : Whether to forbid recursive splitting of a query field
833833
when a direct query fails
@@ -985,6 +985,12 @@ def _submit_requests(
985985
if "meta" in data:
986986
total_data["meta"] = data["meta"]
987987

988+
# otherwise, paginate sequentially
989+
if chunk_size is None or chunk_size < 1:
990+
raise ValueError(
991+
"A positive chunk size must be provided to enable pagination"
992+
)
993+
988994
# Get max number of response pages
989995
max_pages = (
990996
num_chunks if num_chunks is not None else ceil(total_num_docs / chunk_size)
@@ -1024,10 +1030,6 @@ def _submit_requests(
10241030
pbar.close()
10251031
return new_total_data
10261032

1027-
# otherwise, paginate sequentially
1028-
if chunk_size is None:
1029-
raise ValueError("A chunk size must be provided to enable pagination")
1030-
10311033
# Warning to select specific fields only for many results
10321034
if criteria.get("_all_fields", False) and (total_num_docs / chunk_size > 10):
10331035
warnings.warn(

mp_api/client/routes/materials/summary.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import warnings
44
from collections import defaultdict
5+
from itertools import chain, product
56

67
from emmet.core.summary import HasProps, SummaryDoc
78
from emmet.core.symmetry import CrystalSystem
@@ -200,8 +201,9 @@ def search( # noqa: D417
200201
mmnd_inv = {v: k for k, v in min_max_name_dict.items() if k != v}
201202

202203
# Set user query params from `locals`
204+
_locals = locals()
203205
user_settings = {
204-
k: v for k, v in locals().items() if k in min_max_name_dict and v
206+
k: v for k, v in _locals.items() if k in min_max_name_dict and v
205207
}
206208

207209
# Check to see if user specified _search fields using **kwargs,
@@ -328,10 +330,11 @@ def _csrc(x):
328330
"spacegroup_number": 230,
329331
"spacegroup_symbol": 230,
330332
}
333+
batched_symm_query = {}
331334
for k, cardinality in symm_cardinality.items():
332-
if isinstance(symm_vals := locals().get(k), list | tuple | set):
335+
if isinstance(symm_vals := _locals.get(k), list | tuple | set):
333336
if len(symm_vals) < cardinality // 2:
334-
query_params.update({k: ",".join(str(v) for v in symm_vals)})
337+
batched_symm_query[k] = symm_vals
335338
else:
336339
raise MPRestError(
337340
f"Querying `{k}` by a list of values is only "
@@ -378,6 +381,24 @@ def _csrc(x):
378381
if query_params[entry] is not None
379382
}
380383

384+
if batched_symm_query:
385+
ordered_symm_key = sorted(batched_symm_query)
386+
return list(
387+
chain.from_iterable(
388+
self._search( # type: ignore[return-value]
389+
num_chunks=num_chunks,
390+
chunk_size=chunk_size,
391+
all_fields=all_fields,
392+
fields=fields,
393+
**query_params,
394+
**{sk: symm_params[i] for i, sk in enumerate(ordered_symm_key)},
395+
)
396+
for symm_params in product(
397+
*[batched_symm_query[k] for k in ordered_symm_key]
398+
)
399+
)
400+
)
401+
381402
return super()._search( # type: ignore[return-value]
382403
num_chunks=num_chunks,
383404
chunk_size=chunk_size,

0 commit comments

Comments
 (0)