diff --git a/dev/generate_mcp_tools.py b/dev/generate_mcp_tools.py index d4037715..4bd57700 100644 --- a/dev/generate_mcp_tools.py +++ b/dev/generate_mcp_tools.py @@ -59,7 +59,8 @@ def regenerate_tools( COORDINATION_GEOMETRIES_IUPAC, COORDINATION_GEOMETRIES_NAMES, ) -from emmet.core.electronic_structure import BSPathType, DOSProjectionType +from emmet.core.band_theory import BSPathType +from emmet.core.electronic_structure import DOSProjectionType from emmet.core.grain_boundary import GBTypeEnum from emmet.core.mpid import MPID from emmet.core.thermo import ThermoType diff --git a/mp_api/client/mprester.py b/mp_api/client/mprester.py index c2dfefde..5bda5310 100644 --- a/mp_api/client/mprester.py +++ b/mp_api/client/mprester.py @@ -7,7 +7,7 @@ from functools import cache, lru_cache from typing import TYPE_CHECKING -from emmet.core.electronic_structure import BSPathType +from emmet.core.band_theory import BSPathType from emmet.core.mpid import MPID, AlphaID from emmet.core.types.enums import ThermoType from emmet.core.vasp.calc_types import CalcType @@ -1231,9 +1231,11 @@ def get_charge_density_from_task_id( Returns: (Chgcar, (Chgcar, CoreTaskDoc | dict), None): Pymatgen Chgcar object, or tuple with object and CoreTaskDoc """ + # TODO: change when `validate_ids` is updated to return AlphaID + validated_id = AlphaID(validate_ids([task_id])[0].split("-")[-1], prefix="mp") chgcar = self.materials.tasks._query_open_data( bucket="materialsproject-parsed", - key=f"chgcars/{validate_ids([task_id])[0]}.json.gz", + key=f"chgcars/{validated_id.string}.json.gz", decoder=lambda x: load_json(x, deser=True), )[0][0]["data"] diff --git a/mp_api/client/routes/materials/electrodes.py b/mp_api/client/routes/materials/electrodes.py index 1a63b023..0a74fc1c 100644 --- a/mp_api/client/routes/materials/electrodes.py +++ b/mp_api/client/routes/materials/electrodes.py @@ -104,7 +104,9 @@ def search( {f"{param}_min": value[0], f"{param}_max": value[1]} ) elif param == "battery_ids": - query_params[param] = ",".join(validate_ids(value)) + query_params[param] = ",".join( + validate_ids([value] if isinstance(value, str) else value) + ) elif param == "working_ion": query_params["working_ion"] = ",".join( str(ele) diff --git a/mp_api/client/routes/materials/electronic_structure.py b/mp_api/client/routes/materials/electronic_structure.py index 28b02ed2..b0bee09e 100644 --- a/mp_api/client/routes/materials/electronic_structure.py +++ b/mp_api/client/routes/materials/electronic_structure.py @@ -4,8 +4,8 @@ from collections import defaultdict from typing import TYPE_CHECKING +from emmet.core.band_theory import BSPathType from emmet.core.electronic_structure import ( - BSPathType, DOSProjectionType, ElectronicStructureDoc, ) diff --git a/mp_api/client/routes/materials/tasks.py b/mp_api/client/routes/materials/tasks.py index cc707656..ab34c000 100644 --- a/mp_api/client/routes/materials/tasks.py +++ b/mp_api/client/routes/materials/tasks.py @@ -8,6 +8,7 @@ from emmet.core.mpid import MPID, AlphaID from emmet.core.tasks import CoreTaskDoc from emmet.core.trajectory import RelaxTrajectory +from emmet.core.vasp.calc_types import RunType from mp_api.client.core import BaseRester, MPRestError from mp_api.client.core.utils import validate_ids @@ -24,18 +25,28 @@ class TaskRester(BaseRester): primary_key: str = "task_id" delta_backed = True - def get_trajectory(self, task_id: MPID | AlphaID | str) -> dict[str, Any]: + def get_trajectory( + self, task_id: MPID | AlphaID | str, run_type: str | RunType | None = None + ) -> dict[str, Any]: """Returns a Trajectory object containing the geometry of the material throughout a calculation. This is most useful for observing how a material relaxes during a geometry optimization. Args: task_id (str, MPID, AlphaID): Task ID + run_type (str, RunType): Task run type Returns: dict representing emmet.core.trajectory.RelaxTrajectory """ as_alpha = str(AlphaID(task_id, padlen=8)).split("-")[-1] + + predicate = ( + f"WHERE run_type='{str(run_type)}' AND identifier='{as_alpha}'" + if run_type + else f"WHERE identifier='{as_alpha}'" + ) + traj_tbl = DeltaTable( "s3a://materialsproject-parsed/core/trajectories/", storage_options={"AWS_SKIP_SIGNATURE": "true", "AWS_REGION": "us-east-1"}, @@ -48,7 +59,7 @@ def get_trajectory(self, task_id: MPID | AlphaID | str) -> dict[str, Any]: f""" SELECT * FROM traj - WHERE identifier='{as_alpha}' + {predicate}; """ ) .read_all() @@ -96,7 +107,13 @@ def search( if isinstance(task_ids, str): task_ids = [task_ids] - query_params.update({"task_ids": ",".join(validate_ids(task_ids))}) + # TODO: this should just be a join on `validate_ids`, + # once `validate_ids` returns AlphaID + validated = validate_ids(task_ids) + validated += [ + str(AlphaID(task_id.split("-")[-1], padlen=8)) for task_id in validated + ] + query_params["task_ids"] = ",".join(validated) if formula: query_params.update({"formula": formula}) diff --git a/mp_api/client/routes/materials/thermo.py b/mp_api/client/routes/materials/thermo.py index 0ed19818..a2088a7f 100644 --- a/mp_api/client/routes/materials/thermo.py +++ b/mp_api/client/routes/materials/thermo.py @@ -7,6 +7,7 @@ from emmet.core.types.enums import ThermoType from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.core import Element +from pymatgen.core import __version__ as __pmg_version__ from mp_api.client.core import BaseRester from mp_api.client.core.utils import load_json, validate_ids @@ -173,10 +174,12 @@ def get_phase_diagram_from_chemsys( )[0][0].get("phase_diagram") pd = PhaseDiagram.from_dict( - { + { # type: ignore[arg-type] k: v if k != "elements" else [e.get("element", e) for e in v] for k, v in pd_dct.items() # type: ignore[union-attr] - } + } # post pymatgen/-core split, different serialization behavior + if int(__pmg_version__.split(".", 1)[0]) >= 2026 + else pd_dct # pymatgen<=2025.10.7 ) # Ensure el_ref keys are Element objects for PDPlotter. diff --git a/mp_api/mcp/tools.py b/mp_api/mcp/tools.py index 21a0602f..6fcfe8e2 100644 --- a/mp_api/mcp/tools.py +++ b/mp_api/mcp/tools.py @@ -12,7 +12,8 @@ COORDINATION_GEOMETRIES_IUPAC, COORDINATION_GEOMETRIES_NAMES, ) -from emmet.core.electronic_structure import BSPathType, DOSProjectionType +from emmet.core.band_theory import BSPathType +from emmet.core.electronic_structure import DOSProjectionType from emmet.core.grain_boundary import GBTypeEnum from emmet.core.mpid import MPID from emmet.core.summary import HasProps diff --git a/pyproject.toml b/pyproject.toml index 4541d657..45d7a813 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Topic :: Scientific/Engineering", ] dependencies = [ - "pymatgen>=2022.3.7,!=2024.2.20", + "pymatgen>2024.2.20", "typing-extensions>=3.7.4.1", "requests>=2.23.0", "monty>=2024.12.10", diff --git a/requirements/requirements-ubuntu-latest_py3.11.txt b/requirements/requirements-ubuntu-latest_py3.11.txt index deebbe6b..b22e64fb 100644 --- a/requirements/requirements-ubuntu-latest_py3.11.txt +++ b/requirements/requirements-ubuntu-latest_py3.11.txt @@ -12,13 +12,13 @@ bibtexparser==1.4.4 # via pymatgen-core blake3==1.0.8 # via emmet-core -boto3==1.42.90 +boto3==1.42.94 # via mp-api (pyproject.toml) -botocore==1.42.90 +botocore==1.42.94 # via # boto3 # s3transfer -certifi==2026.2.25 +certifi==2026.4.22 # via requests charset-normalizer==3.4.7 # via requests @@ -26,15 +26,15 @@ contourpy==1.3.3 # via matplotlib cycler==0.12.1 # via matplotlib -deltalake==1.5.0 +deltalake==1.5.1 # via mp-api (pyproject.toml) deprecated==1.3.1 # via deltalake -emmet-core==0.86.4rc1 +emmet-core==0.86.4rc2 # via mp-api (pyproject.toml) fonttools==4.62.1 # via matplotlib -idna==3.11 +idna==3.13 # via requests inflect==7.5.0 # via emmet-core @@ -48,7 +48,7 @@ kiwisolver==1.5.0 # via matplotlib latexcodec==3.0.1 # via pybtex -lxml==6.0.4 +lxml==6.1.0 # via pymatgen-core matplotlib==3.10.8 # via pymatgen-core @@ -61,7 +61,7 @@ more-itertools==11.0.2 # via inflect mpmath==1.3.0 # via sympy -narwhals==2.19.0 +narwhals==2.20.0 # via plotly networkx==3.6.1 # via pymatgen-core @@ -93,18 +93,18 @@ plotly==6.7.0 # via pymatgen-core pubchempy==1.0.5 # via emmet-core -pyarrow==23.0.1 +pyarrow==24.0.0 # via mp-api (pyproject.toml) pybtex==0.26.1 # via emmet-core -pydantic==2.13.1 +pydantic==2.13.3 # via # emmet-core # pydantic-settings # pymatgen-io-validation -pydantic-core==2.46.1 +pydantic-core==2.46.3 # via pydantic -pydantic-settings==2.13.1 +pydantic-settings==2.14.0 # via # emmet-core # pymatgen-io-validation @@ -137,7 +137,7 @@ requests==2.33.1 # pymatgen-io-validation ruamel-yaml==0.19.1 # via monty -s3transfer==0.16.0 +s3transfer==0.16.1 # via boto3 scipy==1.17.1 # via pymatgen-core diff --git a/requirements/requirements-ubuntu-latest_py3.11_extras.txt b/requirements/requirements-ubuntu-latest_py3.11_extras.txt index 2b42c376..91d2addb 100644 --- a/requirements/requirements-ubuntu-latest_py3.11_extras.txt +++ b/requirements/requirements-ubuntu-latest_py3.11_extras.txt @@ -31,7 +31,7 @@ attrs==26.1.0 # cyclopts # jsonschema # referencing -authlib==1.6.11 +authlib==1.7.0 # via fastmcp babel==2.18.0 # via sphinx @@ -47,23 +47,23 @@ blinker==1.9.0 # via flask boltons==25.0.0 # via mpcontribs-client -boto3==1.42.90 +boto3==1.42.94 # via mp-api (pyproject.toml) -botocore==1.42.90 +botocore==1.42.94 # via # boto3 # s3transfer bravado==12.0.1 # via mpcontribs-client -bravado-core==6.1.1 +bravado-core==6.3.1 # via bravado -cachetools==7.0.5 +cachetools==7.0.6 # via # mpcontribs-client # py-key-value-aio caio==0.9.25 # via aiofile -certifi==2026.2.25 +certifi==2026.4.22 # via # httpcore # httpx @@ -74,7 +74,7 @@ cfgv==3.5.0 # via pre-commit charset-normalizer==3.4.7 # via requests -click==8.3.2 +click==8.3.3 # via # flask # uvicorn @@ -85,17 +85,18 @@ coverage[toml]==7.13.5 cryptography==46.0.7 # via # authlib + # joserfc # pyjwt # secretstorage custodian==2025.12.14 # via mp-api (pyproject.toml) cycler==0.12.1 # via matplotlib -cyclopts==4.10.2 +cyclopts==4.11.0 # via fastmcp decorator==5.2.1 # via ipython -deltalake==1.5.0 +deltalake==1.5.1 # via mp-api (pyproject.toml) deprecated==1.3.1 # via deltalake @@ -114,7 +115,7 @@ docutils==0.22.4 # sphinx email-validator==2.3.0 # via pydantic -emmet-core[all]==0.86.4rc1 +emmet-core[all]==0.86.4rc2 # via mp-api (pyproject.toml) exceptiongroup==1.3.1 # via fastmcp @@ -124,7 +125,7 @@ executing==2.2.1 # via stack-data fastmcp==3.2.4 # via mp-api (pyproject.toml) -filelock==3.28.0 +filelock==3.29.0 # via # python-discovery # virtualenv @@ -158,9 +159,9 @@ httpx==0.28.1 # mcp httpx-sse==0.4.3 # via mcp -identify==2.6.18 +identify==2.6.19 # via pre-commit -idna==3.11 +idna==3.13 # via # anyio # email-validator @@ -213,6 +214,8 @@ joblib==1.5.3 # via # pymatgen-analysis-diffusion # pymatgen-core +joserfc==1.6.4 + # via authlib json2html==1.3.0 # via mpcontribs-client jsonpointer==3.1.1 @@ -242,7 +245,7 @@ lazy-loader==0.5 # via scikit-image librt==0.9.0 # via mypy -lxml==6.0.4 +lxml==6.1.0 # via pymatgen-core markdown-it-py==4.0.0 # via rich @@ -287,13 +290,13 @@ msgpack==1.1.2 # via # bravado # bravado-core -mypy==1.20.1 +mypy==1.20.2 # via mp-api (pyproject.toml) mypy-extensions==1.1.0 # via # mp-api (pyproject.toml) # mypy -narwhals==2.19.0 +narwhals==2.20.0 # via plotly networkx==3.6.1 # via @@ -349,7 +352,7 @@ parso==0.8.6 # via jedi pathable==0.5.0 # via jsonschema-path -pathspec==1.0.4 +pathspec==1.1.0 # via mypy pexpect==4.9.0 # via ipython @@ -374,7 +377,7 @@ pluggy==1.6.0 # via # pytest # pytest-cov -pre-commit==4.5.1 +pre-commit==4.6.0 # via mp-api (pyproject.toml) prompt-toolkit==3.0.52 # via ipython @@ -388,7 +391,7 @@ pure-eval==0.2.3 # via stack-data py-key-value-aio[filetree,keyring,memory]==0.4.4 # via fastmcp -pyarrow==23.0.1 +pyarrow==24.0.0 # via # emmet-core # mp-api (pyproject.toml) @@ -400,7 +403,7 @@ pycodestyle==2.14.0 # mp-api (pyproject.toml) pycparser==3.0 # via cffi -pydantic[email]==2.13.1 +pydantic[email]==2.13.3 # via # emmet-core # fastmcp @@ -408,9 +411,9 @@ pydantic[email]==2.13.1 # openapi-pydantic # pydantic-settings # pymatgen-io-validation -pydantic-core==2.46.1 +pydantic-core==2.46.3 # via pydantic -pydantic-settings==2.13.1 +pydantic-settings==2.14.0 # via # emmet-core # mcp @@ -448,7 +451,7 @@ pymatgen-core==2026.4.16 # via pymatgen pymatgen-io-validation==0.1.2 # via emmet-core -pymongo==4.16.0 +pymongo==4.17.0 # via # emmet-core # mpcontribs-client @@ -539,7 +542,7 @@ ruamel-yaml==0.19.1 # via # custodian # monty -s3transfer==0.16.0 +s3transfer==0.16.1 # via boto3 scikit-image==0.26.0 # via pymatgen-analysis-defects @@ -556,7 +559,7 @@ seekpath==2.2.1 # via emmet-core shapely==2.1.2 # via pymatgen-analysis-alloys -simplejson==3.20.2 +simplejson==4.1.0 # via # bravado # bravado-core @@ -665,7 +668,7 @@ urllib3==2.6.3 # botocore # requests # types-requests -uvicorn==0.44.0 +uvicorn==0.46.0 # via # fastmcp # mcp diff --git a/requirements/requirements-ubuntu-latest_py3.12.txt b/requirements/requirements-ubuntu-latest_py3.12.txt index 7f00d6af..85ff0200 100644 --- a/requirements/requirements-ubuntu-latest_py3.12.txt +++ b/requirements/requirements-ubuntu-latest_py3.12.txt @@ -12,13 +12,13 @@ bibtexparser==1.4.4 # via pymatgen-core blake3==1.0.8 # via emmet-core -boto3==1.42.90 +boto3==1.42.94 # via mp-api (pyproject.toml) -botocore==1.42.90 +botocore==1.42.94 # via # boto3 # s3transfer -certifi==2026.2.25 +certifi==2026.4.22 # via requests charset-normalizer==3.4.7 # via requests @@ -26,15 +26,15 @@ contourpy==1.3.3 # via matplotlib cycler==0.12.1 # via matplotlib -deltalake==1.5.0 +deltalake==1.5.1 # via mp-api (pyproject.toml) deprecated==1.3.1 # via deltalake -emmet-core==0.86.4rc1 +emmet-core==0.86.4rc2 # via mp-api (pyproject.toml) fonttools==4.62.1 # via matplotlib -idna==3.11 +idna==3.13 # via requests inflect==7.5.0 # via emmet-core @@ -48,7 +48,7 @@ kiwisolver==1.5.0 # via matplotlib latexcodec==3.0.1 # via pybtex -lxml==6.0.4 +lxml==6.1.0 # via pymatgen-core matplotlib==3.10.8 # via pymatgen-core @@ -61,7 +61,7 @@ more-itertools==11.0.2 # via inflect mpmath==1.3.0 # via sympy -narwhals==2.19.0 +narwhals==2.20.0 # via plotly networkx==3.6.1 # via pymatgen-core @@ -93,18 +93,18 @@ plotly==6.7.0 # via pymatgen-core pubchempy==1.0.5 # via emmet-core -pyarrow==23.0.1 +pyarrow==24.0.0 # via mp-api (pyproject.toml) pybtex==0.26.1 # via emmet-core -pydantic==2.13.1 +pydantic==2.13.3 # via # emmet-core # pydantic-settings # pymatgen-io-validation -pydantic-core==2.46.1 +pydantic-core==2.46.3 # via pydantic -pydantic-settings==2.13.1 +pydantic-settings==2.14.0 # via # emmet-core # pymatgen-io-validation @@ -137,7 +137,7 @@ requests==2.33.1 # pymatgen-io-validation ruamel-yaml==0.19.1 # via monty -s3transfer==0.16.0 +s3transfer==0.16.1 # via boto3 scipy==1.17.1 # via pymatgen-core diff --git a/requirements/requirements-ubuntu-latest_py3.12_extras.txt b/requirements/requirements-ubuntu-latest_py3.12_extras.txt index f67ea252..fcf1449e 100644 --- a/requirements/requirements-ubuntu-latest_py3.12_extras.txt +++ b/requirements/requirements-ubuntu-latest_py3.12_extras.txt @@ -31,7 +31,7 @@ attrs==26.1.0 # cyclopts # jsonschema # referencing -authlib==1.6.11 +authlib==1.7.0 # via fastmcp babel==2.18.0 # via sphinx @@ -45,23 +45,23 @@ blinker==1.9.0 # via flask boltons==25.0.0 # via mpcontribs-client -boto3==1.42.90 +boto3==1.42.94 # via mp-api (pyproject.toml) -botocore==1.42.90 +botocore==1.42.94 # via # boto3 # s3transfer bravado==12.0.1 # via mpcontribs-client -bravado-core==6.1.1 +bravado-core==6.3.1 # via bravado -cachetools==7.0.5 +cachetools==7.0.6 # via # mpcontribs-client # py-key-value-aio caio==0.9.25 # via aiofile -certifi==2026.2.25 +certifi==2026.4.22 # via # httpcore # httpx @@ -72,7 +72,7 @@ cfgv==3.5.0 # via pre-commit charset-normalizer==3.4.7 # via requests -click==8.3.2 +click==8.3.3 # via # flask # uvicorn @@ -83,17 +83,18 @@ coverage[toml]==7.13.5 cryptography==46.0.7 # via # authlib + # joserfc # pyjwt # secretstorage custodian==2025.12.14 # via mp-api (pyproject.toml) cycler==0.12.1 # via matplotlib -cyclopts==4.10.2 +cyclopts==4.11.0 # via fastmcp decorator==5.2.1 # via ipython -deltalake==1.5.0 +deltalake==1.5.1 # via mp-api (pyproject.toml) deprecated==1.3.1 # via deltalake @@ -112,7 +113,7 @@ docutils==0.22.4 # sphinx email-validator==2.3.0 # via pydantic -emmet-core[all]==0.86.4rc1 +emmet-core[all]==0.86.4rc2 # via mp-api (pyproject.toml) exceptiongroup==1.3.1 # via fastmcp @@ -122,7 +123,7 @@ executing==2.2.1 # via stack-data fastmcp==3.2.4 # via mp-api (pyproject.toml) -filelock==3.28.0 +filelock==3.29.0 # via # python-discovery # virtualenv @@ -156,9 +157,9 @@ httpx==0.28.1 # mcp httpx-sse==0.4.3 # via mcp -identify==2.6.18 +identify==2.6.19 # via pre-commit -idna==3.11 +idna==3.13 # via # anyio # email-validator @@ -209,6 +210,8 @@ joblib==1.5.3 # via # pymatgen-analysis-diffusion # pymatgen-core +joserfc==1.6.4 + # via authlib json2html==1.3.0 # via mpcontribs-client jsonpointer==3.1.1 @@ -238,7 +241,7 @@ lazy-loader==0.5 # via scikit-image librt==0.9.0 # via mypy -lxml==6.0.4 +lxml==6.1.0 # via pymatgen-core markdown-it-py==4.0.0 # via rich @@ -283,13 +286,13 @@ msgpack==1.1.2 # via # bravado # bravado-core -mypy==1.20.1 +mypy==1.20.2 # via mp-api (pyproject.toml) mypy-extensions==1.1.0 # via # mp-api (pyproject.toml) # mypy -narwhals==2.19.0 +narwhals==2.20.0 # via plotly networkx==3.6.1 # via @@ -345,7 +348,7 @@ parso==0.8.6 # via jedi pathable==0.5.0 # via jsonschema-path -pathspec==1.0.4 +pathspec==1.1.0 # via mypy pexpect==4.9.0 # via ipython @@ -370,7 +373,7 @@ pluggy==1.6.0 # via # pytest # pytest-cov -pre-commit==4.5.1 +pre-commit==4.6.0 # via mp-api (pyproject.toml) prompt-toolkit==3.0.52 # via ipython @@ -384,7 +387,7 @@ pure-eval==0.2.3 # via stack-data py-key-value-aio[filetree,keyring,memory]==0.4.4 # via fastmcp -pyarrow==23.0.1 +pyarrow==24.0.0 # via # emmet-core # mp-api (pyproject.toml) @@ -396,7 +399,7 @@ pycodestyle==2.14.0 # mp-api (pyproject.toml) pycparser==3.0 # via cffi -pydantic[email]==2.13.1 +pydantic[email]==2.13.3 # via # emmet-core # fastmcp @@ -404,9 +407,9 @@ pydantic[email]==2.13.1 # openapi-pydantic # pydantic-settings # pymatgen-io-validation -pydantic-core==2.46.1 +pydantic-core==2.46.3 # via pydantic -pydantic-settings==2.13.1 +pydantic-settings==2.14.0 # via # emmet-core # mcp @@ -444,7 +447,7 @@ pymatgen-core==2026.4.16 # via pymatgen pymatgen-io-validation==0.1.2 # via emmet-core -pymongo==4.16.0 +pymongo==4.17.0 # via # emmet-core # mpcontribs-client @@ -535,7 +538,7 @@ ruamel-yaml==0.19.1 # via # custodian # monty -s3transfer==0.16.0 +s3transfer==0.16.1 # via boto3 scikit-image==0.26.0 # via pymatgen-analysis-defects @@ -552,7 +555,7 @@ seekpath==2.2.1 # via emmet-core shapely==2.1.2 # via pymatgen-analysis-alloys -simplejson==3.20.2 +simplejson==4.1.0 # via # bravado # bravado-core @@ -658,7 +661,7 @@ urllib3==2.6.3 # botocore # requests # types-requests -uvicorn==0.44.0 +uvicorn==0.46.0 # via # fastmcp # mcp