Metrials chemical metadata

Hi all!
I was wondering whether materials qualitative, string-like metadata are available through MAPI.
By this I mean chemical (e.g. oxide, sulfide, phosphate etc) similarly to the already available crystallographic identification.(e.g. spacegroup symbols)

It appears from MAPI’s docs that this kind of info is not there, or am I missing something?

Hi @acarnevali, you can try looking at the tags data from the provenance endpoint, and the description and condensed_structure fields from the robocrys endpoint in the new API.

– Jason

Hi @munrojm!
I am trying to access the Provenance docs to retrieve tags, but I am facing an error I don’t quite understand.

with MPRester(api_key=key) as mpr:
    docs = mpr.provenance.search()

returns

TypeError: __init__() got an unexpected keyword argument 'input_structure'

even though I clearly didn’t pass any keyword arguments. Any idea what’s going on?

This is the traceback, in case it’s needed.

c:\Users\anton\omissis\MP_tags.py in <module>
      19 with MPRester(api_key=key) as mpr:
      20     print("working on it")
----> 21     docs = mpr.provenance.search()
      22     # print(type(docs))
      23     # tags = docs.tags

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in search(self, num_chunks, chunk_size, all_fields, fields, **kwargs)
    784         # documented kwargs.
    785 
--> 786         return self._get_all_documents(
    787             kwargs,
    788             all_fields=all_fields,

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in _get_all_documents(self, query_params, all_fields, fields, chunk_size, num_chunks)
    833         chosen_param = list_entries[0][0] if len(list_entries) > 0 else None
    834 
--> 835         results = self._query_resource(
    836             query_params,
    837             fields=fields,

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in _query_resource(self, criteria, fields, suburl, use_document_model, parallel_param, num_chunks, chunk_size)
    286                     url += "/"
    287 
--> 288             data = self._submit_requests(
    289                 url=url,
    290                 criteria=criteria,

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in _submit_requests(self, url, criteria, use_document_model, parallel_param, num_chunks, chunk_size)
    385         initial_params_list = [{"url": url, "verify": True, "params": copy(crit)} for crit in new_criteria]
    386 
--> 387         initial_data_tuples = self._multi_thread(use_document_model, initial_params_list)
    388 
    389         for data, subtotal, crit_ind in initial_data_tuples:

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in _multi_thread(self, use_document_model, params_list, progress_bar)
    585 
    586                 for future in finished:
--> 587                     data, subtotal = future.result()
    588                     if progress_bar is not None:
    589                         progress_bar.update(len(data["data"]))

c:\Users\anton\miniconda3\envs\mp\lib\concurrent\futures\_base.py in result(self, timeout)
    436                     raise CancelledError()
    437                 elif self._state == FINISHED:
--> 438                     return self.__get_result()
    439 
    440                 self._condition.wait(timeout)

c:\Users\anton\miniconda3\envs\mp\lib\concurrent\futures\_base.py in __get_result(self)
    388         if self._exception:
    389             try:
--> 390                 raise self._exception
    391             finally:
    392                 # Break a reference cycle with the exception in self._exception

c:\Users\anton\miniconda3\envs\mp\lib\concurrent\futures\thread.py in run(self)
     50 
     51         try:
---> 52             result = self.fn(*self.args, **self.kwargs)
     53         except BaseException as exc:
     54             self.future.set_exception(exc)

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\mp_api\core\client.py in _submit_request_and_process(self, url, verify, params, use_document_model)
    624 
    625             if self.monty_decode:
--> 626                 data = json.loads(response.text, cls=MontyDecoder)
    627             else:
    628                 data = json.loads(response.text)

c:\Users\anton\miniconda3\envs\mp\lib\json\__init__.py in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    357     if parse_constant is not None:
    358         kw['parse_constant'] = parse_constant
--> 359     return cls(**kw).decode(s)

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in decode(self, s)
    438         """
    439         d = json.JSONDecoder.decode(self, s)
--> 440         return self.process_decoded(d)
    441 
    442 

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in <dictcomp>(.0)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    426 
    427         if isinstance(d, list):
--> 428             return [self.process_decoded(x) for x in d]
    429 
    430         return d

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in <listcomp>(.0)
    426 
    427         if isinstance(d, list):
--> 428             return [self.process_decoded(x) for x in d]
    429 
    430         return d

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in <dictcomp>(.0)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    426 
    427         if isinstance(d, list):
--> 428             return [self.process_decoded(x) for x in d]
    429 
    430         return d

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in <listcomp>(.0)
    426 
    427         if isinstance(d, list):
--> 428             return [self.process_decoded(x) for x in d]
    429 
    430         return d

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in <dictcomp>(.0)
    423                     return bson.objectid.ObjectId(d["oid"])
    424 
--> 425             return {self.process_decoded(k): self.process_decoded(v) for k, v in d.items()}
    426 
    427         if isinstance(d, list):

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in process_decoded(self, d)
    407                         data = {k: v for k, v in d.items() if not k.startswith("@")}
    408                         if hasattr(cls_, "from_dict"):
--> 409                             return cls_.from_dict(data)
    410                         if pydantic is not None and issubclass(cls_, pydantic.BaseModel):
    411                             return cls_(**data)

c:\Users\anton\miniconda3\envs\mp\lib\site-packages\monty\json.py in from_dict(cls, d)
    176         """
    177         decoded = {k: MontyDecoder().process_decoded(v) for k, v in d.items() if not k.startswith("@")}
--> 178         return cls(**decoded)
    179 
    180     def to_json(self) -> str:

TypeError: __init__() got an unexpected keyword argument 'input_structure'

Thank you!

Hi @acarnevali, which version of mp-api are you using?

– Jason

I am on mp-api 0.23.3

Hi @acarnevali, okay I can recreate this issue. Not sure why bare calls to search aren’t working. I will look into this, but in the mean time you can get the query to work by explicitly passing pagination parameters (chunk_size=5, num_chunks=2 for example).

– Jason