prisma-api 0.4.3__tar.gz → 0.4.5__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.3
3
+ Version: 0.4.5
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
 
@@ -181,6 +181,7 @@ Module-level helpers exported from the package:
181
181
  - `prisma_api.update_dev_mode`
182
182
  - `prisma_api.update_dev_host_port`
183
183
  - `prisma_api.locate_config`
184
+ - `prisma_api.PrismaUpsertError`, `prisma_api.PrismaRowErrorWarning`, `prisma_api.PrismaUnknownFieldsWarning`, `prisma_api.PrismaNewStructureWarning`
184
185
 
185
186
  ## v2 wrapper list
186
187
 
@@ -266,6 +267,28 @@ All methods below are available on `api.v2`.
266
267
  - `get_carbon_zeopp_experimental(mof=None, limit=500, offset=0)`
267
268
  - `get_carbon_zeopp_experimental_item(item_id)`
268
269
 
270
+ ### AutoPrism tables
271
+
272
+ - `get_computation_runs(workflow_id=None, step=None, status=None, limit=500, offset=0)` / `get_computation_run(run_id)`
273
+ - `upsert_computation_runs(payload, timeout=None, raise_on_error=False)`
274
+ - `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
+ - `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)` — deprecated; use the `adsorption_isotherm` methods with `component='H2'`
277
+ - `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
+ - `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
+ - `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
+ - `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`
281
+ - `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)`
282
+
283
+ The getters take `match="exact"` for an exact (case-insensitive) name match
284
+ instead of the default substring match.
285
+
286
+ Rejected rows (HTTP 207, or 400 when nothing is stored) raise
287
+ `PrismaUpsertError` with `raise_on_error=True`, else emit
288
+ `PrismaRowErrorWarning`. Ignored payload fields and newly created MOF records
289
+ emit `PrismaUnknownFieldsWarning` / `PrismaNewStructureWarning`. See
290
+ [API_REFERENCE_V2.md](API_REFERENCE_V2.md#autoprism-tables).
291
+
269
292
  ### TEA, LCA, cases, and scenarios
270
293
 
271
294
  - `get_output_kpis(scenario_id=None, mof=None, good_structure=None, limit=500, offset=0)`
@@ -373,7 +396,8 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
373
396
 
374
397
  ## Additional documentation
375
398
 
376
- - [API_REFERENCE.md](API_REFERENCE.md)
399
+ - [API_REFERENCE_V1.md](API_REFERENCE_V1.md)
400
+ - [API_REFERENCE_V2.md](API_REFERENCE_V2.md)
377
401
  - [DEVELOPMENT_SUMMARY.md](DEVELOPMENT_SUMMARY.md)
378
402
  - [User Guide.md](User%20Guide.md)
379
403
 
@@ -381,4 +405,6 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
381
405
 
382
406
  - Production v2 base URL: `https://prisma-platform.org/api/v2`
383
407
  - Authentication header: `X-API-Key`
384
- - Local development routing is controlled through config and `api.update_dev_mode(True)`
408
+ - Local development routing is selected with `prisma_api.init(local_dev=True)`; the default targets production
409
+ - 0.4.4: the `adsorption-isotherm` endpoints and the 400/notice handling need prisma_cloud >= 0.6.16
410
+ - 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"`.
@@ -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
 
@@ -161,6 +161,7 @@ Module-level helpers exported from the package:
161
161
  - `prisma_api.update_dev_mode`
162
162
  - `prisma_api.update_dev_host_port`
163
163
  - `prisma_api.locate_config`
164
+ - `prisma_api.PrismaUpsertError`, `prisma_api.PrismaRowErrorWarning`, `prisma_api.PrismaUnknownFieldsWarning`, `prisma_api.PrismaNewStructureWarning`
164
165
 
165
166
  ## v2 wrapper list
166
167
 
@@ -246,6 +247,28 @@ All methods below are available on `api.v2`.
246
247
  - `get_carbon_zeopp_experimental(mof=None, limit=500, offset=0)`
247
248
  - `get_carbon_zeopp_experimental_item(item_id)`
248
249
 
250
+ ### AutoPrism tables
251
+
252
+ - `get_computation_runs(workflow_id=None, step=None, status=None, limit=500, offset=0)` / `get_computation_run(run_id)`
253
+ - `upsert_computation_runs(payload, timeout=None, raise_on_error=False)`
254
+ - `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
+ - `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)` — deprecated; use the `adsorption_isotherm` methods with `component='H2'`
257
+ - `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
+ - `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
+ - `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
+ - `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`
261
+ - `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)`
262
+
263
+ The getters take `match="exact"` for an exact (case-insensitive) name match
264
+ instead of the default substring match.
265
+
266
+ Rejected rows (HTTP 207, or 400 when nothing is stored) raise
267
+ `PrismaUpsertError` with `raise_on_error=True`, else emit
268
+ `PrismaRowErrorWarning`. Ignored payload fields and newly created MOF records
269
+ emit `PrismaUnknownFieldsWarning` / `PrismaNewStructureWarning`. See
270
+ [API_REFERENCE_V2.md](API_REFERENCE_V2.md#autoprism-tables).
271
+
249
272
  ### TEA, LCA, cases, and scenarios
250
273
 
251
274
  - `get_output_kpis(scenario_id=None, mof=None, good_structure=None, limit=500, offset=0)`
@@ -353,7 +376,8 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
353
376
 
354
377
  ## Additional documentation
355
378
 
356
- - [API_REFERENCE.md](API_REFERENCE.md)
379
+ - [API_REFERENCE_V1.md](API_REFERENCE_V1.md)
380
+ - [API_REFERENCE_V2.md](API_REFERENCE_V2.md)
357
381
  - [DEVELOPMENT_SUMMARY.md](DEVELOPMENT_SUMMARY.md)
358
382
  - [User Guide.md](User%20Guide.md)
359
383
 
@@ -361,4 +385,6 @@ pytest tests/ -v --cov=prisma_api --cov-report=term-missing
361
385
 
362
386
  - Production v2 base URL: `https://prisma-platform.org/api/v2`
363
387
  - Authentication header: `X-API-Key`
364
- - Local development routing is controlled through config and `api.update_dev_mode(True)`
388
+ - Local development routing is selected with `prisma_api.init(local_dev=True)`; the default targets production
389
+ - 0.4.4: the `adsorption-isotherm` endpoints and the 400/notice handling need prisma_cloud >= 0.6.16
390
+ - 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"`.
@@ -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()