scientific-skills/pymatgen/references/materials_project_api.md
This reference documents how to access and use the Materials Project database through pymatgen's API integration.
The Materials Project is a comprehensive database of computed materials properties, containing data on hundreds of thousands of inorganic crystals and molecules. The API provides programmatic access to this data through the MPRester client.
The Materials Project API client is now in a separate package:
pip install mp-api
export MP_API_KEY="your_api_key_here"
Or add to your shell configuration file (~/.bashrc, ~/.zshrc, etc.)
from mp_api.client import MPRester
# Using environment variable (recommended)
with MPRester() as mpr:
# Perform queries
pass
# Or explicitly pass API key
with MPRester("your_api_key_here") as mpr:
# Perform queries
pass
Important: Always use the with context manager to ensure sessions are properly closed.
with MPRester() as mpr:
# Get all materials with formula
materials = mpr.materials.summary.search(formula="Fe2O3")
for mat in materials:
print(f"Material ID: {mat.material_id}")
print(f"Formula: {mat.formula_pretty}")
print(f"Energy above hull: {mat.energy_above_hull} eV/atom")
print(f"Band gap: {mat.band_gap} eV")
print()
with MPRester() as mpr:
# Get specific material
material = mpr.materials.summary.search(material_ids=["mp-149"])[0]
print(f"Formula: {material.formula_pretty}")
print(f"Space group: {material.symmetry.symbol}")
print(f"Density: {material.density} g/cm³")
with MPRester() as mpr:
# Get all materials in Fe-O system
materials = mpr.materials.summary.search(chemsys="Fe-O")
# Get materials in ternary system
materials = mpr.materials.summary.search(chemsys="Li-Fe-O")
with MPRester() as mpr:
# Materials containing Fe and O
materials = mpr.materials.summary.search(elements=["Fe", "O"])
# Materials containing ONLY Fe and O (excluding others)
materials = mpr.materials.summary.search(
elements=["Fe", "O"],
exclude_elements=True
)
with MPRester() as mpr:
# Get structure
structure = mpr.get_structure_by_material_id("mp-149")
# Get multiple structures
structures = mpr.get_structures(["mp-149", "mp-510", "mp-19017"])
with MPRester() as mpr:
# Get all Fe2O3 structures
materials = mpr.materials.summary.search(formula="Fe2O3")
for mat in materials:
structure = mpr.get_structure_by_material_id(mat.material_id)
print(f"{mat.material_id}: {structure.get_space_group_info()}")
with MPRester() as mpr:
# Materials with specific property ranges
materials = mpr.materials.summary.search(
chemsys="Li-Fe-O",
energy_above_hull=(0, 0.05), # Stable or near-stable
band_gap=(1.0, 3.0), # Semiconducting
)
# Magnetic materials
materials = mpr.materials.summary.search(
elements=["Fe"],
is_magnetic=True
)
# Metals only
materials = mpr.materials.summary.search(
chemsys="Fe-Ni",
is_metal=True
)
with MPRester() as mpr:
# Get most stable materials
materials = mpr.materials.summary.search(
chemsys="Li-Fe-O",
sort_fields=["energy_above_hull"],
num_chunks=1,
chunk_size=10 # Limit to 10 results
)
with MPRester() as mpr:
# Get band structure
bs = mpr.get_bandstructure_by_material_id("mp-149")
# Analyze band structure
if bs:
print(f"Band gap: {bs.get_band_gap()}")
print(f"Is metal: {bs.is_metal()}")
print(f"Direct gap: {bs.get_band_gap()['direct']}")
# Plot
from pymatgen.electronic_structure.plotter import BSPlotter
plotter = BSPlotter(bs)
plotter.show()
with MPRester() as mpr:
# Get DOS
dos = mpr.get_dos_by_material_id("mp-149")
if dos:
# Get band gap from DOS
gap = dos.get_gap()
print(f"Band gap from DOS: {gap} eV")
# Plot DOS
from pymatgen.electronic_structure.plotter import DosPlotter
plotter = DosPlotter()
plotter.add_dos("Total DOS", dos)
plotter.show()
with MPRester() as mpr:
# Get electronic structure data for Fermi surface
bs = mpr.get_bandstructure_by_material_id("mp-149", line_mode=False)
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
with MPRester() as mpr:
# Get entries for phase diagram
entries = mpr.get_entries_in_chemsys("Li-Fe-O")
# Build phase diagram
pd = PhaseDiagram(entries)
# Plot
plotter = PDPlotter(pd)
plotter.show()
from pymatgen.analysis.pourbaix_diagram import PourbaixDiagram, PourbaixPlotter
with MPRester() as mpr:
# Get entries for Pourbaix diagram
entries = mpr.get_pourbaix_entries(["Fe"])
# Build Pourbaix diagram
pb = PourbaixDiagram(entries)
# Plot
plotter = PourbaixPlotter(pb)
plotter.show()
with MPRester() as mpr:
materials = mpr.materials.summary.search(material_ids=["mp-149"])
for mat in materials:
print(f"Formation energy: {mat.formation_energy_per_atom} eV/atom")
print(f"Energy above hull: {mat.energy_above_hull} eV/atom")
with MPRester() as mpr:
# Search for materials with elastic data
materials = mpr.materials.elasticity.search(
chemsys="Fe-O",
bulk_modulus_vrh=(100, 300) # GPa
)
for mat in materials:
print(f"{mat.material_id}: K = {mat.bulk_modulus_vrh} GPa")
with MPRester() as mpr:
# Get dielectric data
materials = mpr.materials.dielectric.search(
material_ids=["mp-149"]
)
for mat in materials:
print(f"Dielectric constant: {mat.e_electronic}")
print(f"Refractive index: {mat.n}")
with MPRester() as mpr:
# Get piezoelectric materials
materials = mpr.materials.piezoelectric.search(
piezoelectric_modulus=(1, 100)
)
with MPRester() as mpr:
# Get surface data
surfaces = mpr.materials.surface_properties.search(
material_ids=["mp-149"]
)
with MPRester() as mpr:
# Search molecules
molecules = mpr.molecules.summary.search(
formula="H2O"
)
for mol in molecules:
print(f"Molecule ID: {mol.molecule_id}")
print(f"Formula: {mol.formula_pretty}")
with MPRester() as mpr:
# Get comprehensive data
materials = mpr.materials.summary.search(
material_ids=["mp-149"],
fields=[
"material_id",
"formula_pretty",
"structure",
"energy_above_hull",
"band_gap",
"density",
"symmetry",
"elasticity",
"magnetic_ordering"
]
)
with MPRester() as mpr:
# Get calculation details
materials = mpr.materials.summary.search(
material_ids=["mp-149"],
fields=["material_id", "origins"]
)
for mat in materials:
print(f"Origins: {mat.origins}")
with MPRester() as mpr:
# Get entries (includes energy and composition)
entries = mpr.get_entries_in_chemsys("Li-Fe-O")
# Entries can be used directly in phase diagram analysis
from pymatgen.analysis.phase_diagram import PhaseDiagram
pd = PhaseDiagram(entries)
# Check stability
for entry in entries[:5]:
e_above_hull = pd.get_e_above_hull(entry)
print(f"{entry.composition.reduced_formula}: {e_above_hull:.3f} eV/atom")
The Materials Project API has rate limits to ensure fair usage:
# Bad: Multiple separate queries
with MPRester() as mpr:
for mp_id in ["mp-149", "mp-510", "mp-19017"]:
struct = mpr.get_structure_by_material_id(mp_id) # 3 API calls
# Good: Single batch query
with MPRester() as mpr:
structs = mpr.get_structures(["mp-149", "mp-510", "mp-19017"]) # 1 API call
import json
# Save results for later use
with MPRester() as mpr:
materials = mpr.materials.summary.search(chemsys="Li-Fe-O")
# Save to file
with open("li_fe_o_materials.json", "w") as f:
json.dump([mat.dict() for mat in materials], f)
# Load cached results
with open("li_fe_o_materials.json", "r") as f:
cached_data = json.load(f)
from mp_api.client.core.client import MPRestError
try:
with MPRester() as mpr:
materials = mpr.materials.summary.search(material_ids=["invalid-id"])
except MPRestError as e:
print(f"API Error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
with MPRester() as mpr:
# Get all stable compounds in a chemical system
materials = mpr.materials.summary.search(
chemsys="Li-Fe-O",
energy_above_hull=(0, 0.001) # Essentially on convex hull
)
print(f"Found {len(materials)} stable compounds")
for mat in materials:
print(f" {mat.formula_pretty} ({mat.material_id})")
with MPRester() as mpr:
# Screen for potential cathode materials
materials = mpr.materials.summary.search(
elements=["Li"], # Must contain Li
energy_above_hull=(0, 0.05), # Near stable
band_gap=(0, 0.5), # Metallic or small gap
)
print(f"Found {len(materials)} potential cathode materials")
with MPRester() as mpr:
# Find materials with specific space group
materials = mpr.materials.summary.search(
chemsys="Fe-O",
spacegroup_number=167 # R-3c (corundum structure)
)
All data retrieved from the Materials Project can be directly used with pymatgen's analysis tools:
with MPRester() as mpr:
# Get structure
struct = mpr.get_structure_by_material_id("mp-149")
# Use with pymatgen analysis
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
sga = SpacegroupAnalyzer(struct)
# Generate surfaces
from pymatgen.core.surface import SlabGenerator
slabgen = SlabGenerator(struct, (1,0,0), 10, 10)
slabs = slabgen.get_slabs()
# Phase diagram analysis
entries = mpr.get_entries_in_chemsys(struct.composition.chemical_system)
from pymatgen.analysis.phase_diagram import PhaseDiagram
pd = PhaseDiagram(entries)
with MPRester() as mpr: