materialsproject / api

New API client for the Materials Project
https://materialsproject.github.io/api/
Other
105 stars 34 forks source link

ValidationError returned from mpr.materials.summary.search in mp-api v0.38.0 #866

Closed KMdraijer closed 7 months ago

KMdraijer commented 7 months ago

Hi,

I am using mp-api v0.38.0 and encountering the following error when trying to retrieve Summary documents for any materials:

Gold = mpr.materials.summary.search(formula='Au')

Returns:

---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[14], line 1
----> 1 mpr.materials.summary.search(formula='Au')

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/routes/materials/summary.py:283, in SummaryRester.search(self, band_gap, chemsys, crystal_system, density, deprecated, e_electronic, e_ionic, e_total, efermi, elastic_anisotropy, elements, energy_above_hull, equilibrium_reaction_energy, exclude_elements, formation_energy, formula, g_reuss, g_voigt, g_vrh, has_props, has_reconstructed, is_gap_direct, is_metal, is_stable, k_reuss, k_voigt, k_vrh, magnetic_ordering, material_ids, n, num_elements, num_sites, num_magnetic_sites, num_unique_magnetic_sites, piezoelectric_modulus, poisson_ratio, possible_species, shape_factor, spacegroup_number, spacegroup_symbol, surface_energy_anisotropy, theoretical, total_energy, total_magnetization, total_magnetization_normalized_formula_units, total_magnetization_normalized_vol, uncorrected_energy, volume, weighted_surface_energy, weighted_work_function, sort_fields, num_chunks, chunk_size, all_fields, fields)
    273     query_params.update(
    274         {"_sort_fields": ",".join([s.strip() for s in sort_fields])}
    275     )
    277 query_params = {
    278     entry: query_params[entry]
    279     for entry in query_params
    280     if query_params[entry] is not None
    281 }
--> 283 return super()._search(
    284     num_chunks=num_chunks,
    285     chunk_size=chunk_size,
    286     all_fields=all_fields,
    287     fields=fields,
    288     **query_params,
    289 )

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:1072, in BaseRester._search(self, num_chunks, chunk_size, all_fields, fields, **kwargs)
   1050 """A generic search method to retrieve documents matching specific parameters.
   1051 
   1052 Arguments:
   (...)
   1067     A list of documents.
   1068 """
   1069 # This method should be customized for each end point to give more user friendly,
   1070 # documented kwargs.
-> 1072 return self._get_all_documents(
   1073     kwargs,
   1074     all_fields=all_fields,
   1075     fields=fields,
   1076     chunk_size=chunk_size,
   1077     num_chunks=num_chunks,
   1078 )

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:1119, in BaseRester._get_all_documents(self, query_params, all_fields, fields, chunk_size, num_chunks)
   1105 list_entries = sorted(
   1106     (
   1107         (key, len(entry.split(",")))
   (...)
   1114     reverse=True,
   1115 )
   1117 chosen_param = list_entries[0][0] if len(list_entries) > 0 else None
-> 1119 results = self._query_resource(
   1120     query_params,
   1121     fields=fields,
   1122     parallel_param=chosen_param,
   1123     chunk_size=chunk_size,
   1124     num_chunks=num_chunks,
   1125 )
   1127 return results["data"]

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:411, in BaseRester._query_resource(self, criteria, fields, suburl, use_document_model, parallel_param, num_chunks, chunk_size, timeout)
    408         if not url.endswith("/"):
    409             url += "/"
--> 411     data = self._submit_requests(
    412         url=url,
    413         criteria=criteria,
    414         use_document_model=use_document_model,
    415         parallel_param=parallel_param,
    416         num_chunks=num_chunks,
    417         chunk_size=chunk_size,
    418         timeout=timeout,
    419     )
    421     return data
    423 except RequestException as ex:

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:552, in BaseRester._submit_requests(self, url, criteria, use_document_model, parallel_param, num_chunks, chunk_size, timeout)
    546 remaining_docs_avail = {}
    548 initial_params_list = [
    549     {"url": url, "verify": True, "params": copy(crit)} for crit in new_criteria
    550 ]
--> 552 initial_data_tuples = self._multi_thread(
    553     use_document_model, initial_params_list
    554 )
    556 for data, subtotal, crit_ind in initial_data_tuples:
    557     subtotals.append(subtotal)

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:766, in BaseRester._multi_thread(self, use_document_model, params_list, progress_bar, timeout)
    763 finished, futures = wait(futures, return_when=FIRST_COMPLETED)
    765 for future in finished:
--> 766     data, subtotal = future.result()
    768     if progress_bar is not None:
    769         progress_bar.update(len(data["data"]))

File ~/software/miniconda3/envs/my_work/lib/python3.9/concurrent/futures/_base.py:439, in Future.result(self, timeout)
    437     raise CancelledError()
    438 elif self._state == FINISHED:
--> 439     return self.__get_result()
    441 self._condition.wait(timeout)
    443 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:

File ~/software/miniconda3/envs/my_work/lib/python3.9/concurrent/futures/_base.py:391, in Future.__get_result(self)
    389 if self._exception:
    390     try:
--> 391         raise self._exception
    392     finally:
    393         # Break a reference cycle with the exception in self._exception
    394         self = None

File ~/software/miniconda3/envs/my_work/lib/python3.9/concurrent/futures/thread.py:58, in _WorkItem.run(self)
     55     return
     57 try:
---> 58     result = self.fn(*self.args, **self.kwargs)
     59 except BaseException as exc:
     60     self.future.set_exception(exc)

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:834, in BaseRester._submit_request_and_process(self, url, verify, params, use_document_model, timeout)
    831 # other sub-urls may use different document models
    832 # the client does not handle this in a particularly smart way currently
    833 if self.document_model and use_document_model:
--> 834     raw_doc_list = [self.document_model.parse_obj(d) for d in data["data"]]  # type: ignore
    836     if len(raw_doc_list) > 0:
    837         data_model, set_fields, _ = self._generate_returned_model(
    838             raw_doc_list[0]
    839         )

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/mp_api/client/core/client.py:834, in <listcomp>(.0)
    831 # other sub-urls may use different document models
    832 # the client does not handle this in a particularly smart way currently
    833 if self.document_model and use_document_model:
--> 834     raw_doc_list = [self.document_model.parse_obj(d) for d in data["data"]]  # type: ignore
    836     if len(raw_doc_list) > 0:
    837         data_model, set_fields, _ = self._generate_returned_model(
    838             raw_doc_list[0]
    839         )

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/typing_extensions.py:2360, in deprecated.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
   2357 @functools.wraps(arg)
   2358 def wrapper(*args, **kwargs):
   2359     warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
-> 2360     return arg(*args, **kwargs)

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/pydantic/main.py:1010, in BaseModel.parse_obj(cls, obj)
   1004 @classmethod
   1005 @typing_extensions.deprecated(
   1006     'The `parse_obj` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20
   1007 )
   1008 def parse_obj(cls: type[Model], obj: Any) -> Model:  # noqa: D102
   1009     warnings.warn('The `parse_obj` method is deprecated; use `model_validate` instead.', DeprecationWarning)
-> 1010     return cls.model_validate(obj)

File ~/software/miniconda3/envs/my_work/lib/python3.9/site-packages/pydantic/main.py:503, in BaseModel.model_validate(cls, obj, strict, from_attributes, context)
    501 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
    502 __tracebackhide__ = True
--> 503 return cls.__pydantic_validator__.validate_python(
    504     obj, strict=strict, from_attributes=from_attributes, context=context
    505 )

ValidationError: 1 validation error for SummaryDoc
has_props
  Input should be a valid list [type=list_type, input_value={'materials': True, 'ther...lse, 'substrates': True}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.4/v/list_type

I encountered it after updating the mp-api package, but I'm unfortunately not sure what previous version I used where it was still working.

munrojm commented 7 months ago

Apologies, please update emmet-core as well. I will fix the dependencies so this won't happen.

munrojm commented 7 months ago

This should be fixed as of the latest release