Metadata-Version: 2.4
Name: materialsgalaxy-api
Version: 0.1.1
Summary: Python client for the MaterialsGalaxy API
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2
Description-Content-Type: text/markdown

# MaterialsGalaxy SDK

Python client for the MaterialsGalaxy API.

## Install

```bash
pip install materialsgalaxy-api
```

For local development from this repository:

```bash
cd sdk
uv sync --dev
```

## Authentication

Pass an API key directly:

```python
from materialsgalaxy import MGClient

with MGClient(api_key="sk-...", base_url="https://materialsgalaxy.iphy.ac.cn/api/v1") as mg:
    structure = mg.materials.get_structure("mg-1")
```

Or set `MATERIALSGALAXY_API_KEY`:

```bash
export MATERIALSGALAXY_API_KEY="sk-..."
```

## Search Materials

`search()` returns a `PagedSummary` model. Use `fields` to request only the fields you need.

```python
from materialsgalaxy import MGClient

with MGClient(base_url="https://materialsgalaxy.iphy.ac.cn/api/v1") as mg:
    page = mg.materials.search(
        elements=["Si", "O"],
        fields=["mg_id", "reduced_formula", "properties.band_gap"],
        page_size=10,
    )

print(page.total)
print(page.data[0].mg_id)
print(page.data[0].properties)
```

## Detail Endpoints

```python
with MGClient(api_key="sk-...") as mg:
    summary = mg.materials.get_summary("mg-1")
    structure = mg.materials.get_structure("mg-1")
    growth = mg.materials.get_single_crystal_growth("mg-1")
    electronic = mg.materials.get_electronic_structure("mg-1", soc=False)
    topology = mg.materials.get_topology("mg-1", soc=False)
    phonons = mg.materials.get_phonons("mg-1")
    ferroelectric = mg.materials.get_ferroelectric("mg-1")
    nonlinear = mg.materials.get_nonlinear_optical("mg-1")

print(structure.symmetry.symbol if structure else None)
print(topology.topo_class if topology else None)
```

## Search Then Fetch Details

```python
with MGClient(api_key="sk-...") as mg:
    page = mg.materials.search(
        formula="SiO2",
        fields=["mg_id", "reduced_formula"],
        page_size=5,
    )
    structures = mg.materials.get_structures([item.mg_id for item in page.data if item.mg_id])

for structure in structures:
    print(structure.mg_id, structure.lattice.volume if structure else None)
```

Use `iter_search()` to page through all matches:

```python
with MGClient(api_key="sk-...") as mg:
    for material in mg.materials.iter_search(
        elements=["Si", "O"],
        fields=["mg_id", "reduced_formula"],
        page_size=100,
    ):
        print(material.mg_id, material.reduced_formula)
```

## Returned Models

The SDK returns Pydantic models that mirror the public API contract:

- `PagedSummary`
- `Summary`
- `CrystalStructure`
- `SingleCrystalGrowth`
- `ElectronicStructure`
- `TopologicalProperties`
- `TopologicalPhonon`
- `Ferroelectric`
- `NonlinearOpticalProperties`

`Summary` fields are optional because `fields=[...]` can request partial summary payloads.

## Errors

```python
from materialsgalaxy import MGClient
from materialsgalaxy.exceptions import MaterialsGalaxyAuthenticationError, MaterialsGalaxyHTTPError

try:
    with MGClient(api_key="sk-...") as mg:
        mg.materials.get_structure("mg-1")
except MaterialsGalaxyAuthenticationError:
    print("Invalid or revoked API key")
except MaterialsGalaxyHTTPError as exc:
    print(exc.status_code, exc.detail)
```
