prisma-api 0.4.4__tar.gz → 0.4.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prisma_api
3
- Version: 0.4.4
3
+ Version: 0.4.6
4
4
  Summary: A package for interacting with PrISMa Platform APIs. PrISMa is a holistic system for numerical synthesis and assessment of Metal-Organic Frameworks and their applications, for Direct Air Capture of CO2. For more information, see: https://prisma.hw.ac.uk.
5
5
  Author-email: RCCS-CaptureTeam <team@prisma-platform.org>
6
6
  License: GNUv3
@@ -165,7 +165,7 @@ The main client exposes these v1 methods:
165
165
  - `get_materials_data(payload={}, separate_experimental=True)`
166
166
  - `update_adsorption_singlepoint(df)`
167
167
  - `update_heat_capacity_all_tidy(df)`
168
- - `update_isotherm_h2(df)`
168
+ - `update_isotherm_h2(df)` — deprecated; still works (the server stores its rows in `adsorption_isotherm`)
169
169
  - `update_mofchecker(df)`
170
170
  - `update_zeopp_metrics(df)`
171
171
 
@@ -213,6 +213,15 @@ All methods below are available on `api.v2`.
213
213
  - `build_case_pack(case_id, scenario_id=None)`
214
214
  - `list_case_packs(source=None, sink=None, region=None, study=None, include_scenarios=False, limit=100, offset=0)`
215
215
 
216
+ ### Case-study library (PrISMa_Platform sync)
217
+
218
+ - `upsert_case_study_library(document, dry_run=False, max_request_bytes=2_400_000, raise_on_error=False, timeout=600)` — sends a `prisma_v2.case_study_library.bundle.v1` document, split into requests if needed; replaces the pipeline 11 ZIP upload
219
+ - `get_case_study_library_bundle(sections=None, timeout=300)`
220
+ - `get_case_study_bundle(case_id, timeout=120)`
221
+ - `latest_case_study_library_sync()` — `None` before the first sync
222
+ - `list_case_study_library_sync_runs(status=None, limit=50, git_commit=None, offset=0)`
223
+ - `list_stale_case_study_library_records()`
224
+
216
225
  ### Catalog and reference data
217
226
 
218
227
  - `get_molecules(name=None, limit=500, offset=0)`
@@ -273,11 +282,15 @@ All methods below are available on `api.v2`.
273
282
  - `upsert_computation_runs(payload, timeout=None, raise_on_error=False)`
274
283
  - `get_adsorption_singlepoint(...)` / `get_adsorption_singlepoint_item(row_id)` / `upsert_adsorption_singlepoint(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
275
284
  - `get_heat_capacity(...)` / `get_heat_capacity_item(row_id)` / `upsert_heat_capacity(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
276
- - `get_isotherm_h2(...)` / `get_isotherm_h2_item(row_id)` / `upsert_isotherm_h2(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — H2 only
277
- - `get_adsorption_isotherm(structure=None, isotherm_id=None, component=None, temperature_K=None, pressure_bar=None, limit=500, offset=0, md5=None)` / `get_adsorption_isotherm_item(row_id)` / `upsert_adsorption_isotherm(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — every gas except H2; needs prisma_cloud **>= 0.6.16** (older servers return 404)
285
+ - `get_isotherm_h2(...)` / `get_isotherm_h2_item(row_id)` / `upsert_isotherm_h2(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — deprecated; use the `adsorption_isotherm` methods with `component='H2'`
286
+ - `get_adsorption_isotherm(structure=None, isotherm_id=None, component=None, temperature_K=None, pressure_bar=None, limit=500, offset=0, md5=None, match=None)` / `get_adsorption_isotherm_item(row_id)` / `upsert_adsorption_isotherm(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — every gas, H2 included; needs prisma_cloud **>= 0.6.16** (older servers return 404)
278
287
  - `get_mofchecker(...)` / `get_mofchecker_item(row_id)` / `upsert_mofchecker(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
279
288
  - `get_zeopp_metrics(...)` / `get_zeopp_metrics_item(row_id)` / `upsert_zeopp_metrics(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
280
- - `get_autoprism_collection(...)` / `upsert_autoprism_collection(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
289
+ - `upsert_autoprism_cifs(cifs, tags=None, create_materials=True, batch_size=50, raise_on_error=False, timeout=300)` — AutoPrism's own CIFs, stored as `{structure}__autoprism_{md5[:12]}.cif`
290
+ - `get_autoprism_collection(...)` / `upsert_autoprism_collection(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True, cif_tags=None)`
291
+
292
+ The getters take `match="exact"` for an exact (case-insensitive) name match
293
+ instead of the default substring match.
281
294
 
282
295
  Rejected rows (HTTP 207, or 400 when nothing is stored) raise
283
296
  `PrismaUpsertError` with `raise_on_error=True`, else emit
@@ -403,3 +416,5 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
403
416
  - Authentication header: `X-API-Key`
404
417
  - Local development routing is selected with `prisma_api.init(local_dev=True)`; the default targets production
405
418
  - 0.4.4: the `adsorption-isotherm` endpoints and the 400/notice handling need prisma_cloud >= 0.6.16
419
+ - 0.4.5: H2 isotherms go through `upsert_adsorption_isotherm` (prisma_cloud >= 0.6.16); the H2-only methods and the `isotherm_H2s` collection key are deprecated. New `upsert_autoprism_cifs` uses the existing bundle upsert endpoint. AutoPrism getters take `match="exact"`.
420
+ - 0.4.6: case-study library sync methods (`upsert_case_study_library` and the export, sync-run and stale-record readers) for the prisma_cloud `case-study-library` endpoints, which replace ingest pipeline 11.
@@ -145,7 +145,7 @@ The main client exposes these v1 methods:
145
145
  - `get_materials_data(payload={}, separate_experimental=True)`
146
146
  - `update_adsorption_singlepoint(df)`
147
147
  - `update_heat_capacity_all_tidy(df)`
148
- - `update_isotherm_h2(df)`
148
+ - `update_isotherm_h2(df)` — deprecated; still works (the server stores its rows in `adsorption_isotherm`)
149
149
  - `update_mofchecker(df)`
150
150
  - `update_zeopp_metrics(df)`
151
151
 
@@ -193,6 +193,15 @@ All methods below are available on `api.v2`.
193
193
  - `build_case_pack(case_id, scenario_id=None)`
194
194
  - `list_case_packs(source=None, sink=None, region=None, study=None, include_scenarios=False, limit=100, offset=0)`
195
195
 
196
+ ### Case-study library (PrISMa_Platform sync)
197
+
198
+ - `upsert_case_study_library(document, dry_run=False, max_request_bytes=2_400_000, raise_on_error=False, timeout=600)` — sends a `prisma_v2.case_study_library.bundle.v1` document, split into requests if needed; replaces the pipeline 11 ZIP upload
199
+ - `get_case_study_library_bundle(sections=None, timeout=300)`
200
+ - `get_case_study_bundle(case_id, timeout=120)`
201
+ - `latest_case_study_library_sync()` — `None` before the first sync
202
+ - `list_case_study_library_sync_runs(status=None, limit=50, git_commit=None, offset=0)`
203
+ - `list_stale_case_study_library_records()`
204
+
196
205
  ### Catalog and reference data
197
206
 
198
207
  - `get_molecules(name=None, limit=500, offset=0)`
@@ -253,11 +262,15 @@ All methods below are available on `api.v2`.
253
262
  - `upsert_computation_runs(payload, timeout=None, raise_on_error=False)`
254
263
  - `get_adsorption_singlepoint(...)` / `get_adsorption_singlepoint_item(row_id)` / `upsert_adsorption_singlepoint(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
255
264
  - `get_heat_capacity(...)` / `get_heat_capacity_item(row_id)` / `upsert_heat_capacity(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
256
- - `get_isotherm_h2(...)` / `get_isotherm_h2_item(row_id)` / `upsert_isotherm_h2(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — H2 only
257
- - `get_adsorption_isotherm(structure=None, isotherm_id=None, component=None, temperature_K=None, pressure_bar=None, limit=500, offset=0, md5=None)` / `get_adsorption_isotherm_item(row_id)` / `upsert_adsorption_isotherm(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — every gas except H2; needs prisma_cloud **>= 0.6.16** (older servers return 404)
265
+ - `get_isotherm_h2(...)` / `get_isotherm_h2_item(row_id)` / `upsert_isotherm_h2(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — deprecated; use the `adsorption_isotherm` methods with `component='H2'`
266
+ - `get_adsorption_isotherm(structure=None, isotherm_id=None, component=None, temperature_K=None, pressure_bar=None, limit=500, offset=0, md5=None, match=None)` / `get_adsorption_isotherm_item(row_id)` / `upsert_adsorption_isotherm(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)` — every gas, H2 included; needs prisma_cloud **>= 0.6.16** (older servers return 404)
258
267
  - `get_mofchecker(...)` / `get_mofchecker_item(row_id)` / `upsert_mofchecker(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
259
268
  - `get_zeopp_metrics(...)` / `get_zeopp_metrics_item(row_id)` / `upsert_zeopp_metrics(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
260
- - `get_autoprism_collection(...)` / `upsert_autoprism_collection(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True)`
269
+ - `upsert_autoprism_cifs(cifs, tags=None, create_materials=True, batch_size=50, raise_on_error=False, timeout=300)` — AutoPrism's own CIFs, stored as `{structure}__autoprism_{md5[:12]}.cif`
270
+ - `get_autoprism_collection(...)` / `upsert_autoprism_collection(payload, meta_provenance=None, repo_dir=None, timeout=None, raise_on_error=False, check_ids=True, cif_tags=None)`
271
+
272
+ The getters take `match="exact"` for an exact (case-insensitive) name match
273
+ instead of the default substring match.
261
274
 
262
275
  Rejected rows (HTTP 207, or 400 when nothing is stored) raise
263
276
  `PrismaUpsertError` with `raise_on_error=True`, else emit
@@ -383,3 +396,5 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
383
396
  - Authentication header: `X-API-Key`
384
397
  - Local development routing is selected with `prisma_api.init(local_dev=True)`; the default targets production
385
398
  - 0.4.4: the `adsorption-isotherm` endpoints and the 400/notice handling need prisma_cloud >= 0.6.16
399
+ - 0.4.5: H2 isotherms go through `upsert_adsorption_isotherm` (prisma_cloud >= 0.6.16); the H2-only methods and the `isotherm_H2s` collection key are deprecated. New `upsert_autoprism_cifs` uses the existing bundle upsert endpoint. AutoPrism getters take `match="exact"`.
400
+ - 0.4.6: case-study library sync methods (`upsert_case_study_library` and the export, sync-run and stale-record readers) for the prisma_cloud `case-study-library` endpoints, which replace ingest pipeline 11.
@@ -0,0 +1,31 @@
1
+ from importlib.metadata import PackageNotFoundError
2
+ from importlib.metadata import version as _version
3
+
4
+ try:
5
+ __version__ = _version("prisma_api")
6
+ except PackageNotFoundError: # running from a source tree without installing
7
+ __version__ = "0+unknown"
8
+
9
+
10
+ from prisma_api.config import locate_config, update_dev_host_port, update_dev_mode
11
+ from prisma_api.prisma_api import prisma_api as init # main client
12
+ from prisma_api.prisma_api_v2 import ( # v2 client (also api.v2) and upsert failure signals
13
+ PrismaAPIv2,
14
+ PrismaNewStructureWarning,
15
+ PrismaRowErrorWarning,
16
+ PrismaUnknownFieldsWarning,
17
+ PrismaUpsertError,
18
+ )
19
+
20
+ __all__ = [
21
+ "PrismaAPIv2",
22
+ "PrismaNewStructureWarning",
23
+ "PrismaRowErrorWarning",
24
+ "PrismaUnknownFieldsWarning",
25
+ "PrismaUpsertError",
26
+ "__version__",
27
+ "init",
28
+ "locate_config",
29
+ "update_dev_host_port",
30
+ "update_dev_mode",
31
+ ]
@@ -1,11 +1,10 @@
1
1
  import os
2
2
  import sys
3
3
  from pathlib import Path
4
+
4
5
  import pandas as pd
5
- import yaml
6
6
  import platformdirs
7
-
8
-
7
+ import yaml
9
8
 
10
9
  ### Helper functions for config management
11
10
 
@@ -42,7 +41,7 @@ def load_config():
42
41
  return cfg
43
42
 
44
43
  # Internal function to create config.yaml
45
- def create_config_file(api_key: str = None):
44
+ def create_config_file(api_key: str | None = None):
46
45
  """
47
46
  Create config.yaml. If api_key is None, prompt via CLI.
48
47
 
@@ -1,14 +1,15 @@
1
+ import math
1
2
  import os
2
3
  import warnings
3
- from .config import get_or_create_config, update_dev_mode as _update_dev_mode
4
- from .prisma_api_v2 import PrismaAPIv2
5
- from pathlib import Path
4
+
5
+ import numpy as np
6
6
  import pandas as pd
7
7
  import requests
8
8
 
9
- import numpy as np
10
- import json
11
- import math
9
+ from .config import get_or_create_config
10
+ from .config import update_dev_mode as _update_dev_mode
11
+ from .prisma_api_v2 import PrismaAPIv2
12
+
12
13
 
13
14
  def _safe_nan_check(x):
14
15
  if x is None:
@@ -23,7 +24,7 @@ def _safe_nan_check(x):
23
24
 
24
25
 
25
26
  # prisma_api main class
26
- class prisma_api():
27
+ class prisma_api:
27
28
 
28
29
  def __init__(self, use_config_file=True, local_dev: bool = False,
29
30
  upload_timeout: int = 120):
@@ -91,7 +92,7 @@ class prisma_api():
91
92
  )
92
93
  return _update_dev_mode(dev)
93
94
 
94
- def get_mofs(self, payload={}):
95
+ def get_mofs(self, payload: dict | None = None):
95
96
 
96
97
  api = self
97
98
 
@@ -105,7 +106,7 @@ class prisma_api():
105
106
  "Content-Type": "application/json"
106
107
  }
107
108
 
108
- response = requests.post(url, json=payload, headers=headers, timeout=60)
109
+ response = requests.post(url, json=payload or {}, headers=headers, timeout=60)
109
110
  data = response.json()['data']
110
111
 
111
112
  data = pd.DataFrame.from_dict(data)
@@ -113,7 +114,7 @@ class prisma_api():
113
114
  return data
114
115
 
115
116
 
116
- def get_carbon_isotherms(self, payload={}):
117
+ def get_carbon_isotherms(self, payload: dict | None = None):
117
118
 
118
119
  api = self
119
120
 
@@ -128,7 +129,7 @@ class prisma_api():
128
129
  }
129
130
 
130
131
  try:
131
- response = requests.post(url, json=payload, headers=headers, timeout=60)
132
+ response = requests.post(url, json=payload or {}, headers=headers, timeout=60)
132
133
  data = response.json()['data']
133
134
 
134
135
  data = pd.DataFrame.from_dict(data)
@@ -147,11 +148,11 @@ class prisma_api():
147
148
 
148
149
  return data
149
150
 
150
- except Exception as e:
151
+ except Exception: # noqa: BLE001 - v1 contract: print and return empty
151
152
  print("Error retrieving carbon isotherms: check that the query parameter names are correct.")
152
153
  return pd.DataFrame()
153
154
 
154
- def get_carbon_data_nested(self, payload={}, safe_names=False):
155
+ def get_carbon_data_nested(self, payload: dict | None = None, safe_names=False):
155
156
  """
156
157
  Get carbon data with nested structure, returned as separate DataFrames.
157
158
 
@@ -180,7 +181,7 @@ class prisma_api():
180
181
  }
181
182
 
182
183
  try:
183
- response = requests.post(url, json=payload, headers=headers, timeout=60)
184
+ response = requests.post(url, json=payload or {}, headers=headers, timeout=60)
184
185
  data = response.json()
185
186
 
186
187
  col_names_carbon = data.get('meta', {}).get('original_column_names', {})
@@ -234,11 +235,11 @@ class prisma_api():
234
235
  }
235
236
  }
236
237
 
237
- except Exception as e:
238
+ except Exception as e: # noqa: BLE001 - v1 contract: print and return empty
238
239
  print(f"Error retrieving carbon data nested: {e}")
239
240
  return {}
240
241
 
241
- def get_materials_data(self, payload={}, separate_experimental=True):
242
+ def get_materials_data(self, payload: dict | None = None, separate_experimental=True):
242
243
  """
243
244
  Args:
244
245
  payload: Dictionary containing query parameters for filtering.
@@ -279,12 +280,12 @@ class prisma_api():
279
280
  source_key = None
280
281
  for name, endpoint in urls.items():
281
282
  try:
282
- response = requests.post(endpoint, json=payload, headers=headers, timeout=60)
283
+ response = requests.post(endpoint, json=payload or {}, headers=headers, timeout=60)
283
284
  data_raw = response.json()
284
285
  if data_raw.get('data'):
285
286
  source_key = name
286
287
  break
287
- except Exception:
288
+ except Exception: # noqa: BLE001, S112 - endpoint fallback: try the next one
288
289
  continue
289
290
 
290
291
  if data_raw is None:
@@ -406,7 +407,7 @@ class prisma_api():
406
407
  'meta': {'source': source_key},
407
408
  }
408
409
 
409
- except Exception as e:
410
+ except Exception as e: # noqa: BLE001 - v1 contract: print and return empty
410
411
  print(f"Error retrieving materials data: {e}")
411
412
  return {}
412
413
 
@@ -446,8 +447,6 @@ class prisma_api():
446
447
  if df.empty:
447
448
  return "[]"
448
449
 
449
- import numpy as np
450
- import json
451
450
 
452
451
  # Use pandas to_json which handles NaN properly, then parse back
453
452
  df_clean = df.copy()