Skip to content

Commit 41f0bde

Browse files
precommit
1 parent 4747310 commit 41f0bde

File tree

11 files changed

+39
-58
lines changed

11 files changed

+39
-58
lines changed

mp_api/client/core/client.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ def __init__(
9292
session: requests.Session | None = None,
9393
s3_client: Any | None = None,
9494
debug: bool = False,
95-
monty_decode: bool = True,
9695
use_document_model: bool = True,
9796
timeout: int = 20,
9897
headers: dict | None = None,
9998
mute_progress_bars: bool = SETTINGS.MUTE_PROGRESS_BARS,
99+
**kwargs,
100100
):
101101
"""Initialize the REST API helper class.
102102
@@ -121,13 +121,13 @@ def __init__(
121121
advanced usage only.
122122
s3_client: boto3 S3 client object with which to connect to the object stores.ct to the object stores.ct to the object stores.
123123
debug: if True, print the URL for every request
124-
monty_decode: Decode the data using monty into python objects
125124
use_document_model: If False, skip the creating the document model and return data
126125
as a dictionary. This can be simpler to work with but bypasses data validation
127126
and will not give auto-complete for available fields.
128127
timeout: Time in seconds to wait until a request timeout error is thrown
129128
headers: Custom headers for localhost connections.
130129
mute_progress_bars: Whether to disable progress bars.
130+
**kwargs: access to legacy kwargs that may be in the process of being deprecated
131131
"""
132132
# TODO: think about how to migrate from PMG_MAPI_KEY
133133
self.api_key = api_key or os.getenv("MP_API_KEY")
@@ -136,7 +136,6 @@ def __init__(
136136
)
137137
self.debug = debug
138138
self.include_user_agent = include_user_agent
139-
self.monty_decode = monty_decode
140139
self.use_document_model = use_document_model
141140
self.timeout = timeout
142141
self.headers = headers or {}
@@ -151,6 +150,12 @@ def __init__(
151150
self._session = session
152151
self._s3_client = s3_client
153152

153+
if "monty_decode" in kwargs:
154+
warnings.warn(
155+
"Ignoring `monty_decode`, as it is no longer a supported option in `mp_api`."
156+
"The client by default returns results consistent with `monty_decode=True`."
157+
)
158+
154159
@property
155160
def session(self) -> requests.Session:
156161
if not self._session:
@@ -265,7 +270,7 @@ def _post_resource(
265270
response = self.session.post(url, json=payload, verify=True, params=params)
266271

267272
if response.status_code == 200:
268-
data = load_json(response.text, deser=self.monty_decode)
273+
data = load_json(response.text)
269274
if self.document_model and use_document_model:
270275
if isinstance(data["data"], dict):
271276
data["data"] = self.document_model.model_validate(data["data"]) # type: ignore
@@ -333,7 +338,7 @@ def _patch_resource(
333338
response = self.session.patch(url, json=payload, verify=True, params=params)
334339

335340
if response.status_code == 200:
336-
data = load_json(response.text, deser=self.monty_decode)
341+
data = load_json(response.text)
337342
if self.document_model and use_document_model:
338343
if isinstance(data["data"], dict):
339344
data["data"] = self.document_model.model_validate(data["data"]) # type: ignore
@@ -384,10 +389,7 @@ def _query_open_data(
384389
Returns:
385390
dict: MontyDecoded data
386391
"""
387-
if not decoder:
388-
389-
def decoder(x):
390-
return load_json(x, deser=self.monty_decode)
392+
decoder = decoder or load_json
391393

392394
file = open(
393395
f"s3://{bucket}/{key}",
@@ -997,7 +999,7 @@ def _submit_request_and_process(
997999
)
9981000

9991001
if response.status_code == 200:
1000-
data = load_json(response.text, deser=self.monty_decode)
1002+
data = load_json(response.text)
10011003
# other sub-urls may use different document models
10021004
# the client does not handle this in a particularly smart way currently
10031005
if self.document_model and use_document_model:
@@ -1302,12 +1304,10 @@ def count(self, criteria: dict | None = None) -> int | str:
13021304
"""
13031305
criteria = criteria or {}
13041306
user_preferences = (
1305-
self.monty_decode,
13061307
self.use_document_model,
13071308
self.mute_progress_bars,
13081309
)
1309-
self.monty_decode, self.use_document_model, self.mute_progress_bars = (
1310-
False,
1310+
self.use_document_model, self.mute_progress_bars = (
13111311
False,
13121312
True,
13131313
) # do not waste cycles decoding
@@ -1329,7 +1329,6 @@ def count(self, criteria: dict | None = None) -> int | str:
13291329
)
13301330

13311331
(
1332-
self.monty_decode,
13331332
self.use_document_model,
13341333
self.mute_progress_bars,
13351334
) = user_preferences

mp_api/client/mprester.py

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ def __init__(
125125
endpoint: str | None = None,
126126
notify_db_version: bool = False,
127127
include_user_agent: bool = True,
128-
monty_decode: bool = True,
129128
use_document_model: bool = True,
130129
session: Session | None = None,
131130
headers: dict | None = None,
132131
mute_progress_bars: bool = _MAPI_SETTINGS.MUTE_PROGRESS_BARS,
132+
**kwargs,
133133
):
134134
"""Initialize the MPRester.
135135
@@ -157,14 +157,13 @@ def __init__(
157157
making the API request. This helps MP support pymatgen users, and
158158
is similar to what most web browsers send with each page request.
159159
Set to False to disable the user agent.
160-
monty_decode: Decode the data using monty into python objects
161160
use_document_model: If False, skip the creating the document model and return data
162161
as a dictionary. This can be simpler to work with but bypasses data validation
163162
and will not give auto-complete for available fields.
164163
session: Session object to use. By default (None), the client will create one.
165164
headers: Custom headers for localhost connections.
166165
mute_progress_bars: Whether to mute progress bars.
167-
166+
**kwargs: access to legacy kwargs that may be in the process of being deprecated
168167
"""
169168
# SETTINGS tries to read API key from ~/.config/.pmgrc.yaml
170169
api_key = api_key or os.getenv("MP_API_KEY") or SETTINGS.get("PMG_MAPI_KEY")
@@ -187,7 +186,6 @@ def __init__(
187186
headers=self.headers,
188187
)
189188
self.use_document_model = use_document_model
190-
self.monty_decode = monty_decode
191189
self.mute_progress_bars = mute_progress_bars
192190
self._contribs = None
193191

@@ -224,6 +222,12 @@ def __init__(
224222
if not self.endpoint.endswith("/"):
225223
self.endpoint += "/"
226224

225+
if "monty_decode" in kwargs:
226+
warnings.warn(
227+
"Ignoring `monty_decode`, as it is no longer a supported option in `mp_api`."
228+
"The client by default returns results consistent with `monty_decode=True`."
229+
)
230+
227231
# Check if emmet version of server is compatible
228232
emmet_version = MPRester.get_emmet_version(self.endpoint)
229233

@@ -260,7 +264,6 @@ def __init__(
260264
endpoint=self.endpoint,
261265
include_user_agent=include_user_agent,
262266
session=self.session,
263-
monty_decode=self.monty_decode,
264267
use_document_model=self.use_document_model,
265268
headers=self.headers,
266269
mute_progress_bars=self.mute_progress_bars,
@@ -278,15 +281,11 @@ def __init__(
278281
suffix_split = cls.suffix.split("/")
279282

280283
if len(suffix_split) == 1:
281-
# Disable monty decode on nested data which may give errors
282-
monty_disable = cls in [TaskRester, ProvenanceRester]
283-
monty_decode = False if monty_disable else self.monty_decode
284284
rester = cls(
285285
api_key=api_key,
286286
endpoint=self.endpoint,
287287
include_user_agent=include_user_agent,
288288
session=self.session,
289-
monty_decode=monty_decode,
290289
use_document_model=self.use_document_model,
291290
headers=self.headers,
292291
mute_progress_bars=self.mute_progress_bars,
@@ -309,14 +308,11 @@ def __init__(
309308
def __core_custom_getattr(_self, _attr, _rester_map):
310309
if _attr in _rester_map:
311310
cls = _rester_map[_attr]
312-
monty_disable = cls in [TaskRester, ProvenanceRester]
313-
monty_decode = False if monty_disable else self.monty_decode
314311
rester = cls(
315312
api_key=api_key,
316313
endpoint=self.endpoint,
317314
include_user_agent=include_user_agent,
318315
session=self.session,
319-
monty_decode=monty_decode,
320316
use_document_model=self.use_document_model,
321317
headers=self.headers,
322318
mute_progress_bars=self.mute_progress_bars,
@@ -752,7 +748,7 @@ def get_entries(
752748
# Need to store object to permit de-duplication
753749
entries.add(ComputedStructureEntry.from_dict(entry_dict))
754750

755-
return [e if self.monty_decode else e.as_dict() for e in entries]
751+
return list(entries)
756752

757753
def get_pourbaix_entries(
758754
self,
@@ -1190,18 +1186,12 @@ def get_entries_in_chemsys(
11901186
)
11911187
)
11921188

1193-
if not self.monty_decode:
1194-
entries = [ComputedStructureEntry.from_dict(entry) for entry in entries]
1195-
11961189
if use_gibbs:
11971190
# replace the entries with GibbsComputedStructureEntry
11981191
from pymatgen.entries.computed_entries import GibbsComputedStructureEntry
11991192

12001193
entries = GibbsComputedStructureEntry.from_entries(entries, temp=use_gibbs)
12011194

1202-
if not self.monty_decode:
1203-
entries = [entry.as_dict() for entry in entries]
1204-
12051195
return entries
12061196

12071197
def get_bandstructure_by_material_id(
@@ -1312,7 +1302,7 @@ def get_charge_density_from_task_id(
13121302
kwargs = dict(
13131303
bucket="materialsproject-parsed",
13141304
key=f"chgcars/{validate_ids([task_id])[0]}.json.gz",
1315-
decoder=lambda x: load_json(x, deser=self.monty_decode),
1305+
decoder=lambda x: load_json(x, deser=True),
13161306
)
13171307
chgcar = self.materials.tasks._query_open_data(**kwargs)[0]
13181308
if not chgcar:
@@ -1493,17 +1483,11 @@ def get_cohesive_energy(
14931483
conventional_unit_cell=False,
14941484
)
14951485
for entry in entries:
1496-
# Ensure that this works with monty_decode = False and True
1497-
if not self.monty_decode:
1498-
entry["uncorrected_energy_per_atom"] = entry["energy"] / sum(
1499-
entry["composition"].values()
1500-
)
1501-
else:
1502-
entry = {
1503-
"data": entry.data,
1504-
"uncorrected_energy_per_atom": entry.uncorrected_energy_per_atom,
1505-
"composition": entry.composition,
1506-
}
1486+
entry = {
1487+
"data": entry.data,
1488+
"uncorrected_energy_per_atom": entry.uncorrected_energy_per_atom,
1489+
"composition": entry.composition,
1490+
}
15071491

15081492
mp_id = entry["data"]["material_id"]
15091493
if (run_type := entry["data"]["run_type"]) not in energies[mp_id]:

mp_api/client/routes/_general_store.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class GeneralStoreRester(BaseRester): # pragma: no cover
99
suffix = "_general_store"
1010
document_model = GeneralStoreDoc # type: ignore
1111
primary_key = "submission_id"
12-
monty_decode = False
1312
use_document_model = False
1413

1514
def add_item(self, kind: str, markdown: str, meta: dict): # pragma: no cover

mp_api/client/routes/_messages.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class MessagesRester(BaseRester): # pragma: no cover
1111
suffix = "_messages"
1212
document_model = MessagesDoc # type: ignore
1313
primary_key = "title"
14-
monty_decode = False
1514
use_document_model = False
1615

1716
def set_message(

mp_api/client/routes/_user_settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class UserSettingsRester(BaseRester): # pragma: no cover
99
suffix = "_user_settings"
1010
document_model = UserSettingsDoc # type: ignore
1111
primary_key = "consumer_id"
12-
monty_decode = False
1312
use_document_model = False
1413

1514
def create_user_settings(self, consumer_id, settings):

mp_api/client/routes/materials/electronic_structure.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from pymatgen.electronic_structure.core import OrbitalType, Spin
1515

1616
from mp_api.client.core import BaseRester, MPRestError
17-
from mp_api.client.core.utils import validate_ids
17+
from mp_api.client.core.utils import load_json, validate_ids
1818

1919
if TYPE_CHECKING:
2020
from pymatgen.electronic_structure.dos import CompleteDos
@@ -158,7 +158,6 @@ def es_rester(self) -> ElectronicStructureRester:
158158
endpoint=self.base_endpoint,
159159
include_user_agent=self.include_user_agent,
160160
session=self.session,
161-
monty_decode=self.monty_decode,
162161
use_document_model=self.use_document_model,
163162
headers=self.headers,
164163
mute_progress_bars=self.mute_progress_bars,
@@ -269,6 +268,7 @@ def get_bandstructure_from_task_id(self, task_id: str):
269268
result = self._query_open_data(
270269
bucket="materialsproject-parsed",
271270
key=f"bandstructures/{validate_ids([task_id])[0]}.json.gz",
271+
decoder=lambda x: load_json(x, deser=True),
272272
)[0]
273273
except OSError:
274274
result = None
@@ -473,6 +473,7 @@ def get_dos_from_task_id(self, task_id: str) -> CompleteDos:
473473
result = self._query_open_data(
474474
bucket="materialsproject-parsed",
475475
key=f"dos/{validate_ids([task_id])[0]}.json.gz",
476+
decoder=lambda x: load_json(x, deser=True),
476477
)[0]
477478
except OSError:
478479
result = None

mp_api/client/routes/materials/materials.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def get_structure_by_material_id(
128128

129129
if response and response[0]:
130130
response = response[0]
131-
# Ensure that return type is a Structure regardless of `monty_decode` or `model_dump` output
131+
# Ensure that return type is a Structure regardless of `model_dump`
132132
if isinstance(response[field], dict):
133133
response[field] = Structure.from_dict(response[field])
134134
elif isinstance(response[field], list) and any(

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ authors = [
99
]
1010
description = "API Client for the Materials Project"
1111
readme = "README.md"
12-
requires-python = ">=3.10"
12+
requires-python = ">=3.11"
1313
license = { text = "modified BSD" }
1414
classifiers = [
1515
"Programming Language :: Python :: 3",

tests/materials/test_tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
@pytest.fixture
1212
def rester():
13-
rester = TaskRester(monty_decode=False)
13+
rester = TaskRester()
1414
yield rester
1515
rester.session.close()
1616

tests/test_client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ def test_generic_get_methods(rester):
6363
endpoint=mpr.endpoint,
6464
include_user_agent=True,
6565
session=mpr.session,
66-
# Disable monty decode on nested data which may give errors
67-
monty_decode=rester not in [TaskRester, ProvenanceRester],
6866
use_document_model=True,
6967
)
7068

0 commit comments

Comments
 (0)