Source code for mpinterfaces.rest

from __future__ import division, unicode_literals

"""
This is essentially just a clone of the MPRester object in pymatgen with
slight modifications to work with MaterialsWeb.

This module provides classes to interface with the MaterialsWeb REST
API v2 to enable the creation of data structures and pymatgen objects using
MaterialsWeb data.
"""

import json
import warnings

from monty.json import MontyDecoder
from pymatgen.core.structure import Structure

__author__ = "Michael Ashton"
__copyright__ = "Copyright 2017, Henniggroup"
__maintainer__ = "Joshua J. Gabriel"
__email__ = "joshgabriel92@gmail.com"
__status__ = "Production"
__date__ = "March 3, 2017"


[docs]class MWRester(object): """ A class to conveniently interface with the MaterialsWeb REST interface. The recommended way to use MWRester is with the "with" context manager to ensure that sessions are properly closed after usage:: with MWRester("API_KEY") as m: do_something MWRester uses the "requests" package, which provides for HTTP connection pooling. All connections are made via https for security. Args: api_key (str): A String API key for accessing the MaterialsWeb REST interface. Please obtain your API key at https://www.materialsweb.org. endpoint (str): Url of endpoint to access the MaterialsWeb REST interface. Defaults to the standard MaterialsWeb REST address, but can be changed to other urls implementing a similar interface. """ supported_properties = ("energy", "energy_per_atom", "volume", "formation_energy_per_atom", "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard", "elements", "nelements", "e_above_hull", "hubbards", "is_compatible", "spacegroup", "task_ids", "band_gap", "density", "icsd_id", "icsd_ids", "cif", "total_magnetization", "material_id", "oxide_type", "tags", "elasticity") supported_task_properties = ("energy", "energy_per_atom", "volume", "formation_energy_per_atom", "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard", "elements", "nelements", "e_above_hull", "hubbards", "is_compatible", "spacegroup", "band_gap", "density", "icsd_id", "cif") def __init__(self, api_key=None, endpoint="https://www.materialsweb.org/rest"): if api_key is not None: self.api_key = api_key else: self.api_key = "" self.preamble = endpoint import requests self.session = requests.Session() self.session.headers = {"x-api-key": self.api_key} def __enter__(self): """ Support for "with" context. """ return self def __exit__(self, exc_type, exc_val, exc_tb): """ Support for "with" context. """ self.session.close() def _make_request(self, sub_url, payload=None, method="GET", mp_decode=True): response = None url = self.preamble + sub_url try: if method == "POST": response = self.session.post(url, data=payload, verify=True) else: # For now, the SSL certificate is being annoying and # won't verify. Once it does, we can change this back # to verify=True. response = self.session.get(url, params=payload, verify=False) if response.status_code in [200, 400]: if mp_decode: data = json.loads(response.text, cls=MontyDecoder) else: data = json.loads(response.text) if data["valid_response"]: if data.get("warning"): warnings.warn(data["warning"]) return data["response"] else: raise MWRestError(data["error"]) raise MWRestError("REST query returned with error status code {}" .format(response.status_code)) except Exception as ex: msg = "{}. Content: {}".format(str(ex), response.content)\ if hasattr(response, "content") else str(ex) raise MWRestError(msg)
[docs] def get_data(self, chemsys_formula_id, data_type="vasp", prop=""): """ Flexible method to get any data using the MaterialsWeb REST interface. Generally used by other methods for more specific queries. Format of REST return is *always* a list of dict (regardless of the number of pieces of data returned. The general format is as follows: [{"material_id": material_id, "property_name" : value}, ...] Args: chemsys_formula_id (str): A chemical system (e.g., Li-Fe-O), or formula (e.g., Fe2O3) or materials_id (e.g., mp-1234). data_type (str): Type of data to return. Currently can either be "vasp" or "exp". prop (str): Property to be obtained. Should be one of the MWRester.supported_task_properties. Leave as empty string for a general list of useful properties. """ sub_url = "/materials/%s/%s" % (chemsys_formula_id, data_type) if prop: sub_url += "/" + prop return self._make_request(sub_url)
[docs] def get_structure_by_material_id(self, material_id, final=True): """ Get a Structure corresponding to a material_id. Args: material_id (str): MaterialsWeb material_id (a string, e.g., mp-1234). final (bool): Whether to get the final structure, or the initial (pre-relaxation) structure. Defaults to True. Returns: Structure object. """ prop = "final_structure" if final else "initial_structure" data = self.get_data(material_id) return Structure.from_str(data[0][prop], fmt="json")
[docs]class MWRestError(Exception): """ Exception class for MWRestAdaptor. Raised when the query has problems, e.g., bad query format. """ pass