Skip to content

Commit f9e4598

Browse files
committed
Add a Jupyter Notebook example
1 parent 3f59605 commit f9e4598

6 files changed

Lines changed: 1575 additions & 31 deletions

File tree

backend/packages/acidwatch/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ acidwatch = "acidwatch.cli:app"
1616
[dependency-groups]
1717
dev = [
1818
"mypy",
19+
"pandas-stubs>=3.0.3.260530",
1920
"pytest",
2021
"pytest-asyncio",
2122
"ruff",

backend/packages/acidwatch/src/acidwatch/cli/toplevel.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,4 @@ def run(
7575
)
7676

7777
print("Result:")
78-
for key, fval in sim_result.results[-1].concentrations.items():
79-
if fval < 0.1:
80-
continue
81-
82-
rprint(f" {key}: {val:.1f} ppm")
78+
rprint(sim_result)

backend/packages/acidwatch/src/acidwatch/client.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from __future__ import annotations
2+
3+
import io
24
import time
35
from uuid import UUID
46
from pydantic.alias_generators import to_camel
57
from pydantic import BaseModel, ConfigDict, RootModel, Field
68
from typing_extensions import Doc
7-
from typing import Annotated, Any, Literal
9+
from typing import Annotated, Any, Literal, Iterator
810
import httpx
11+
import pandas as pd
912

1013

1114
DEFAULT_API_URL = "https://backend-acidwatch-prod.radix.equinor.com"
@@ -38,6 +41,24 @@ class Model(BaseModel):
3841
parameters: dict[str, _Parameter]
3942

4043

44+
class Models(RootModel[list[Model]]):
45+
def __getitem__(self, item: int) -> Model:
46+
return self.root[item]
47+
48+
def __iter__(self) -> Iterator[Model]: # type: ignore
49+
return self.root.__iter__()
50+
51+
def _repr_markdown_(self) -> str:
52+
out = io.StringIO()
53+
print("| # | ModelID | Name |", file=out)
54+
print("|---|---------|------|", file=out)
55+
56+
for index, model in enumerate(self):
57+
print(f"| {index} | {model.model_id} | {model.display_name} |", file=out)
58+
59+
return out.getvalue()
60+
61+
4162
class _IndivitualResult(BaseModel):
4263
concentrations: dict[str, float]
4364

@@ -74,15 +95,10 @@ def __init__(
7495
) -> None:
7596
super().__init__(base_url=api_url)
7697

77-
def list_models(self) -> list[Model]:
98+
def list_models(self) -> Models:
7899
resp = self.get("/models")
79-
80100
assert resp.status_code == 200
81-
82-
root_model = RootModel[list[Model]]
83-
object = root_model.model_validate_json(resp.content)
84-
85-
return object.root
101+
return Models.model_validate_json(resp.content)
86102

87103
def run_model(
88104
self,
@@ -93,7 +109,7 @@ def run_model(
93109
temperature: float = 25,
94110
pressure: float = 10,
95111
retries: int = 9999,
96-
) -> SimulationResult:
112+
) -> pd.DataFrame:
97113
response = self.post(
98114
"/simulations",
99115
json={
@@ -123,7 +139,16 @@ def run_model(
123139

124140
res = _SimulationResult.model_validate_json(response.content)
125141
if isinstance(res.root, SimulationResult):
126-
return res.root
142+
substances: set[str] = set()
143+
for r in res.root.results:
144+
substances |= set(r.concentrations.keys())
145+
146+
return pd.DataFrame(
147+
{
148+
s: [r.concentrations[s] for r in res.root.results]
149+
for s in substances
150+
}
151+
)
127152

128153
time.sleep(0.5)
129154

backend/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies = [
3232
[project.optional-dependencies]
3333
docs = ["griffe-typingdoc", "mkdocs-material", "mkdocstrings[python]"]
3434
pg = ["psycopg2-binary"]
35+
notebook = ["jupyter"]
3536

3637
[dependency-groups]
3738
dev = [

0 commit comments

Comments
 (0)