pyrestoolbox 3.6.0__tar.gz → 3.7.1__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.
Files changed (138) hide show
  1. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/.github/workflows/build-wheels.yml +15 -15
  2. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/.github/workflows/tests.yml +4 -4
  3. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/.gitignore +7 -6
  4. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/Cargo.lock +1 -1
  5. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/Cargo.toml +1 -1
  6. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/PKG-INFO +1 -1
  7. pyrestoolbox-3.7.1/mcp/DEPLOYMENT.md +53 -0
  8. pyrestoolbox-3.7.1/mcp/Dockerfile +23 -0
  9. pyrestoolbox-3.7.1/mcp/README.md +87 -0
  10. pyrestoolbox-3.7.1/mcp/pyproject.toml +26 -0
  11. pyrestoolbox-3.7.1/mcp/pyrestoolbox_mcp/__init__.py +3 -0
  12. pyrestoolbox-3.7.1/mcp/pyrestoolbox_mcp/serialize.py +50 -0
  13. pyrestoolbox-3.7.1/mcp/pyrestoolbox_mcp/server.py +295 -0
  14. pyrestoolbox-3.7.1/mcp/tests/test_server.py +183 -0
  15. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyproject.toml +1 -1
  16. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/__init__.py +23 -2
  17. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/brine/_lib_vle_engine.py +98 -22
  18. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/brine/brine.py +11 -12
  19. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/dca/dca.py +575 -19
  20. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/brine.rst +3 -3
  21. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/changelist.rst +18 -0
  22. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/dca.rst +372 -8
  23. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/gas.rst +9 -3
  24. pyrestoolbox-3.7.1/pyrestoolbox/docs/index.rst +62 -0
  25. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/layer.rst +2 -2
  26. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/nodal.rst +9 -6
  27. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/oil.rst +7 -8
  28. pyrestoolbox-3.7.1/pyrestoolbox/docs/plyasunov.rst +230 -0
  29. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/simtools.rst +7 -3
  30. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/gas/gas.py +18 -28
  31. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/layer/layer.py +1 -1
  32. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/nodal/nodal.py +2 -2
  33. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/plyasunov/plyasunov_model.py +9 -2
  34. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/zfactor/mod.rs +2 -33
  35. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/LICENSE +0 -0
  36. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/MANIFEST.in +0 -0
  37. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/README.rst +0 -0
  38. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/ResToolbox/privacy_policy.md +0 -0
  39. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/benchmark_rust_vs_python.py +0 -0
  40. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/build_pure_python.py +0 -0
  41. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/_accelerator.py +0 -0
  42. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/brine/__init__.py +0 -0
  43. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/brine/_lib_salting_library.py +0 -0
  44. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/classes/__init__.py +0 -0
  45. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/classes/classes.py +0 -0
  46. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/constants/__init__.py +0 -0
  47. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/constants/constants.py +0 -0
  48. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/dca/__init__.py +0 -0
  49. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/examples.ipynb +0 -0
  50. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/bot.png +0 -0
  51. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
  52. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/bot_img.png +0 -0
  53. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/dry_gas.png +0 -0
  54. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
  55. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/influence.png +0 -0
  56. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/properties_df.png +0 -0
  57. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/sgof.png +0 -0
  58. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/img/swof.png +0 -0
  59. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/library.rst +0 -0
  60. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/matbal.rst +0 -0
  61. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
  62. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
  63. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/recommend.rst +0 -0
  64. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/docs/sensitivity.rst +0 -0
  65. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/gas/__init__.py +0 -0
  66. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/gas/_hydrate.py +0 -0
  67. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/layer/__init__.py +0 -0
  68. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/library/__init__.py +0 -0
  69. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/library/component_library.xlsx +0 -0
  70. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/library/library.py +0 -0
  71. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/matbal/__init__.py +0 -0
  72. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/matbal/matbal.py +0 -0
  73. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/nodal/__init__.py +0 -0
  74. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/__init__.py +0 -0
  75. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_compressibility.py +0 -0
  76. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_constants.py +0 -0
  77. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_correlations.py +0 -0
  78. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_density.py +0 -0
  79. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_harmonize.py +0 -0
  80. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_pvt_class.py +0 -0
  81. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_rate.py +0 -0
  82. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_separator.py +0 -0
  83. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_tables.py +0 -0
  84. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/oil/_utils.py +0 -0
  85. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/plyasunov/__init__.py +0 -0
  86. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/plyasunov/iapws_if97.py +0 -0
  87. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/plyasunov/water_properties.py +0 -0
  88. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/recommend/__init__.py +0 -0
  89. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/recommend/recommend.py +0 -0
  90. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/sensitivity/__init__.py +0 -0
  91. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
  92. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/shared_fns/__init__.py +0 -0
  93. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/shared_fns/shared_fns.py +0 -0
  94. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/__init__.py +0 -0
  95. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/_aquifer.py +0 -0
  96. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/_decks.py +0 -0
  97. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/_pvt_tables.py +0 -0
  98. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/_relperm.py +0 -0
  99. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/_vfp.py +0 -0
  100. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/simtools/simtools.py +0 -0
  101. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/validate/__init__.py +0 -0
  102. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/pyrestoolbox/validate/validate.py +0 -0
  103. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/setup.cfg +0 -0
  104. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/setup.py +0 -0
  105. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/bessel.rs +0 -0
  106. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/critical_properties/mod.rs +0 -0
  107. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/dca/hyperbolic.rs +0 -0
  108. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/dca/mod.rs +0 -0
  109. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/dca/ransac.rs +0 -0
  110. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/gas_viscosity/mod.rs +0 -0
  111. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/gwr.rs +0 -0
  112. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/lib.rs +0 -0
  113. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/matbal/mod.rs +0 -0
  114. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/matbal/objective.rs +0 -0
  115. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/oil/density.rs +0 -0
  116. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/oil/mod.rs +0 -0
  117. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/pseudopressure.rs +0 -0
  118. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/spycher_pruess/mod.rs +0 -0
  119. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/spycher_pruess/solubility.rs +0 -0
  120. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/alpha.rs +0 -0
  121. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/bip.rs +0 -0
  122. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/components.rs +0 -0
  123. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/eos.rs +0 -0
  124. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/flash.rs +0 -0
  125. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/fugacity.rs +0 -0
  126. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/k_init.rs +0 -0
  127. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/mod.rs +0 -0
  128. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vle/rachford_rice.rs +0 -0
  129. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/constants.rs +0 -0
  130. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/friction.rs +0 -0
  131. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/holdup_bb.rs +0 -0
  132. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/holdup_gray.rs +0 -0
  133. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/holdup_wg.rs +0 -0
  134. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/ift.rs +0 -0
  135. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/march.rs +0 -0
  136. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/mod.rs +0 -0
  137. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/pvt_helpers.rs +0 -0
  138. {pyrestoolbox-3.6.0 → pyrestoolbox-3.7.1}/src/vlp/static_column.rs +0 -0
@@ -20,9 +20,9 @@ jobs:
20
20
  matrix:
21
21
  os: [ubuntu-latest, macos-14, windows-latest]
22
22
  steps:
23
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v5
24
24
 
25
- - uses: actions/setup-python@v5
25
+ - uses: actions/setup-python@v6
26
26
  with:
27
27
  python-version: "3.12"
28
28
 
@@ -84,7 +84,7 @@ jobs:
84
84
  # ilt-inversion may not have matching wheels on PyPI yet).
85
85
  CIBW_TEST_SKIP: "*-manylinux* *-macosx* cp38-* cp39-*"
86
86
 
87
- - uses: actions/upload-artifact@v4
87
+ - uses: actions/upload-artifact@v6
88
88
  with:
89
89
  name: wheels-${{ matrix.os }}
90
90
  path: ./wheelhouse/*.whl
@@ -95,9 +95,9 @@ jobs:
95
95
  runs-on: macos-13
96
96
  if: false # Enable when macos-13 runners are available, or use cross-compilation
97
97
  steps:
98
- - uses: actions/checkout@v4
98
+ - uses: actions/checkout@v5
99
99
 
100
- - uses: actions/setup-python@v5
100
+ - uses: actions/setup-python@v6
101
101
  with:
102
102
  python-version: "3.12"
103
103
 
@@ -114,7 +114,7 @@ jobs:
114
114
  python -c "from pyrestoolbox._accelerator import get_status; s = get_status(); print(s); assert s['rust_available'], f'Rust not loaded: {s}'"
115
115
  CIBW_TEST_REQUIRES: "numpy"
116
116
 
117
- - uses: actions/upload-artifact@v4
117
+ - uses: actions/upload-artifact@v6
118
118
  with:
119
119
  name: wheels-macos-x86
120
120
  path: ./wheelhouse/*.whl
@@ -124,9 +124,9 @@ jobs:
124
124
  name: Build pure-Python wheel
125
125
  runs-on: ubuntu-latest
126
126
  steps:
127
- - uses: actions/checkout@v4
127
+ - uses: actions/checkout@v5
128
128
 
129
- - uses: actions/setup-python@v5
129
+ - uses: actions/setup-python@v6
130
130
  with:
131
131
  python-version: "3.12"
132
132
 
@@ -136,7 +136,7 @@ jobs:
136
136
  - name: Build pure-Python wheel
137
137
  run: python build_pure_python.py
138
138
 
139
- - uses: actions/upload-artifact@v4
139
+ - uses: actions/upload-artifact@v6
140
140
  with:
141
141
  name: wheels-pure-python
142
142
  path: ./dist/*.whl
@@ -146,9 +146,9 @@ jobs:
146
146
  name: Build source distribution
147
147
  runs-on: ubuntu-latest
148
148
  steps:
149
- - uses: actions/checkout@v4
149
+ - uses: actions/checkout@v5
150
150
 
151
- - uses: actions/setup-python@v5
151
+ - uses: actions/setup-python@v6
152
152
  with:
153
153
  python-version: "3.12"
154
154
 
@@ -161,7 +161,7 @@ jobs:
161
161
  - name: Build sdist
162
162
  run: maturin sdist --out dist
163
163
 
164
- - uses: actions/upload-artifact@v4
164
+ - uses: actions/upload-artifact@v6
165
165
  with:
166
166
  name: sdist
167
167
  path: ./dist/*.tar.gz
@@ -179,7 +179,7 @@ jobs:
179
179
  id-token: write # trusted publishing
180
180
  contents: write # create the GitHub Release
181
181
  steps:
182
- - uses: actions/download-artifact@v4
182
+ - uses: actions/download-artifact@v7
183
183
  with:
184
184
  path: dist
185
185
  merge-multiple: true
@@ -190,7 +190,7 @@ jobs:
190
190
  packages-dir: dist/
191
191
 
192
192
  # ── Create a notes-only GitHub Release (no binaries; PyPI is canonical) ──
193
- - uses: actions/checkout@v4
193
+ - uses: actions/checkout@v5
194
194
 
195
195
  - name: Extract release notes from changelist
196
196
  run: |
@@ -218,7 +218,7 @@ jobs:
218
218
  PY
219
219
 
220
220
  - name: Create GitHub Release
221
- uses: softprops/action-gh-release@v2
221
+ uses: softprops/action-gh-release@v3
222
222
  with:
223
223
  name: ${{ github.ref_name }}
224
224
  body_path: release_notes.md
@@ -15,9 +15,9 @@ jobs:
15
15
  name: Pure Python (PYRESTOOLBOX_NO_RUST=1)
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v5
19
19
 
20
- - uses: actions/setup-python@v5
20
+ - uses: actions/setup-python@v6
21
21
  with:
22
22
  python-version: "3.10"
23
23
 
@@ -34,9 +34,9 @@ jobs:
34
34
  name: Rust-accelerated (parity tests)
35
35
  runs-on: ubuntu-latest
36
36
  steps:
37
- - uses: actions/checkout@v4
37
+ - uses: actions/checkout@v5
38
38
 
39
- - uses: actions/setup-python@v5
39
+ - uses: actions/setup-python@v6
40
40
  with:
41
41
  python-version: "3.10"
42
42
 
@@ -18,6 +18,7 @@ __pycache__/
18
18
  # Claude Code
19
19
  .claude/
20
20
  CLAUDE.md
21
+ HANDOFF.md
21
22
 
22
23
  # Jupyter checkpoints
23
24
  .ipynb_checkpoints/
@@ -36,9 +37,9 @@ target/
36
37
  *.rtf
37
38
  *.VFP
38
39
  *.png
39
-
40
- # Standalone ILT development (lives in ilt-inversion repo)
41
- ilt/
42
- benchmark_ilt.py
43
- benchmark_rust.py
44
- BUILD_INSTRUCTIONS.txt
40
+
41
+ # Standalone ILT development (lives in ilt-inversion repo)
42
+ ilt/
43
+ benchmark_ilt.py
44
+ benchmark_rust.py
45
+ BUILD_INSTRUCTIONS.txt
@@ -152,7 +152,7 @@ dependencies = [
152
152
 
153
153
  [[package]]
154
154
  name = "pyrestoolbox-native"
155
- version = "3.6.0"
155
+ version = "3.7.0"
156
156
  dependencies = [
157
157
  "pyo3",
158
158
  "rug",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pyrestoolbox-native"
3
- version = "3.6.0"
3
+ version = "3.7.0"
4
4
  edition = "2021"
5
5
  license = "GPL-3.0-or-later"
6
6
  description = "Rust acceleration extensions for pyResToolbox"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrestoolbox
3
- Version: 3.6.0
3
+ Version: 3.7.1
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
@@ -0,0 +1,53 @@
1
+ # pyrestoolbox-mcp: deployment note for the Mawson platform team
2
+
3
+ ## What this is
4
+
5
+ An MCP (Model Context Protocol) server exposing pyResToolbox, a petroleum
6
+ engineering calculation library (gas/oil/brine PVT, nodal analysis, decline
7
+ curve analysis, material balance). Source: https://github.com/mwburgoyne/pyResToolbox
8
+ (server code in `mcp/`). Contact: Mark Burgoyne.
9
+
10
+ It gives an LLM seven tools: three discovery/dispatch tools that reach the
11
+ library's full public API (about 125 functions), a correlation-method
12
+ recommender, and three one-shot calculation wrappers. Module documentation
13
+ with worked examples is served as MCP resources. Wrong inputs return errors
14
+ that list the valid options, so the model self-corrects without help.
15
+
16
+ ## Security properties
17
+
18
+ - Pure computation. The server makes no outbound network calls, reads no
19
+ external data sources, and writes nothing to disk. Requests contain only
20
+ numeric/string calculation inputs; responses are JSON numbers and text.
21
+ - No credentials, no state, no user data. Nothing is retained between
22
+ requests.
23
+ - Licence: GPL-3.0. Internal use is not distribution, so no obligations are
24
+ triggered, and the source is public in any case.
25
+
26
+ ## How to deploy
27
+
28
+ 1. Build the container from the repo's `mcp/` directory (Dockerfile
29
+ included; pyresToolbox version is pinned via a build arg). No base-image
30
+ requirements beyond python:3.11-slim.
31
+ 2. Run it anywhere inside the Santos network. It listens on port 8000 and
32
+ serves MCP streamable HTTP at `/mcp`. It is stateless: replicas can sit
33
+ behind a load balancer without session affinity.
34
+ 3. Put your standard API gateway in front for authentication. The server
35
+ itself does not authenticate; it expects to live behind the gateway.
36
+ 4. Register the endpoint URL with Mawson as a remote MCP server.
37
+
38
+ If Mawson does not support remote MCP servers and needs an OpenAPI tool
39
+ spec instead, tell us; the tool layer is plain typed Python and a REST
40
+ wrapper is straightforward.
41
+
42
+ ## Sizing
43
+
44
+ Single-digit milliseconds to low seconds per calculation, CPU-bound, modest
45
+ memory (numpy/scipy stack, roughly 500 MB resident). One small container is
46
+ enough to start; scale horizontally if usage grows.
47
+
48
+ ## Updates
49
+
50
+ Version bumps are deliberate: rebuild the image with a new
51
+ `PYRESTOOLBOX_VERSION` build arg after the library publishes a release.
52
+ The calculation library is regression-tested (900+ tests, frozen numerical
53
+ baselines, documentation examples verified in CI).
@@ -0,0 +1,23 @@
1
+ # pyrestoolbox-mcp: remote MCP server (streamable HTTP)
2
+ # Build from the mcp/ directory: docker build -t pyrestoolbox-mcp .
3
+ # Run: docker run -p 8000:8000 pyrestoolbox-mcp
4
+ # MCP endpoint: http://<host>:8000/mcp
5
+
6
+ FROM python:3.11-slim
7
+
8
+ # Pin the library version for reproducible corporate deployments; bump
9
+ # deliberately and rebuild.
10
+ ARG PYRESTOOLBOX_VERSION=3.7.0
11
+
12
+ WORKDIR /app
13
+ COPY . /app/mcp
14
+
15
+ RUN pip install --no-cache-dir "pyrestoolbox==${PYRESTOOLBOX_VERSION}" /app/mcp
16
+
17
+ # Non-root runtime user
18
+ RUN useradd --create-home --shell /usr/sbin/nologin mcp
19
+ USER mcp
20
+
21
+ EXPOSE 8000
22
+
23
+ CMD ["pyrestoolbox-mcp", "--transport", "streamable-http", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,87 @@
1
+ # pyrestoolbox-mcp
2
+
3
+ MCP (Model Context Protocol) server exposing the
4
+ [pyrestoolbox](https://github.com/mwburgoyne/pyResToolbox) reservoir
5
+ engineering library to agents without a Python execution environment
6
+ (Claude Desktop, claude.ai connectors, other MCP hosts).
7
+
8
+ If your agent CAN run Python, prefer `pip install pyrestoolbox` directly -
9
+ the library ships its full documentation inside the wheel
10
+ (`pyrestoolbox.docs_dir()`), and native code execution is more flexible than
11
+ any tool surface.
12
+
13
+ ## Design
14
+
15
+ A small meta-tool surface instead of one MCP tool per library function:
16
+
17
+ | Tool | Purpose |
18
+ |---|---|
19
+ | `list_functions(module?)` | Module map, or public functions of one module |
20
+ | `describe(name)` | Signature + docstring for `module.function` |
21
+ | `call(name, arguments)` | Invoke any public function with keyword args |
22
+ | `recommend_methods(...)` | Correlation-method recommendations with rationale |
23
+ | `co2_brine_props(...)` | One-shot CO2-saturated brine properties |
24
+ | `sw_brine_props(...)` | One-shot multicomponent gas-saturated brine properties |
25
+ | `fit_and_forecast(...)` | Fit a decline model and forecast in one call |
26
+
27
+ Every module's RST documentation (shipped in the pyrestoolbox wheel) is
28
+ exposed as an MCP resource: `docs://gas`, `docs://oil`, `docs://index`, ...
29
+
30
+ Correlation methods are passed as strings (`"zmethod": "DAK"`); an invalid
31
+ method string returns an error listing the valid options, so agents
32
+ self-correct in one round trip. Results are JSON: numpy arrays become lists,
33
+ DataFrames become `{columns, records}`, non-finite floats become null.
34
+
35
+ ## Install and configure
36
+
37
+ ```
38
+ pip install pyrestoolbox-mcp # once published; or: pip install ./mcp
39
+ ```
40
+
41
+ Claude Code:
42
+
43
+ ```
44
+ claude mcp add pyrestoolbox -- pyrestoolbox-mcp
45
+ ```
46
+
47
+ Claude Desktop (`claude_desktop_config.json`):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "pyrestoolbox": {
53
+ "command": "pyrestoolbox-mcp"
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Remote deployment (enterprise LLM platforms)
60
+
61
+ The server also runs as a remote MCP server over streamable HTTP:
62
+
63
+ ```
64
+ pyrestoolbox-mcp --transport streamable-http --host 0.0.0.0 --port 8000
65
+ ```
66
+
67
+ It is stateless (no session affinity needed behind a load balancer) and
68
+ serves the MCP endpoint at `/mcp`. A `Dockerfile` is included; put an API
69
+ gateway in front for authentication. See `DEPLOYMENT.md` for the platform
70
+ team one-pager.
71
+
72
+ ## Tests
73
+
74
+ ```
75
+ PYTHONPATH=<repo>:<repo>/mcp python3 -m pytest mcp/tests/ -q
76
+ ```
77
+
78
+ ## Notes
79
+
80
+ - Units default to oilfield (psia, deg F, ft, mD, cP); pass `metric: true`
81
+ where the function supports it. The plyasunov module is SI (K, MPa).
82
+ - The oil module is scalar-only; gas and brine functions accept lists.
83
+ - Stateful classes (`GasPVT`, `CO2_Brine_Mixture`, `SoreideWhitson`,
84
+ `DeclineResult`) are not exposed through `call` - the one-shot wrapper
85
+ tools cover the common workflows.
86
+ - File-writing simtools functions keep their `export=False` defaults, so
87
+ calls return table text rather than touching disk.
@@ -0,0 +1,26 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pyrestoolbox-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server exposing the pyrestoolbox reservoir engineering library"
9
+ license = {text = "GPL-3.0-or-later"}
10
+ authors = [{name = "Mark W. Burgoyne", email = "mark.w.burgoyne@gmail.com"}]
11
+ keywords = ["mcp", "petroleum", "reservoir", "pyrestoolbox"]
12
+ requires-python = ">=3.10"
13
+ dependencies = [
14
+ "mcp>=1.2",
15
+ "pyrestoolbox>=3.7",
16
+ ]
17
+ readme = "README.md"
18
+
19
+ [project.urls]
20
+ Homepage = "https://github.com/mwburgoyne/pyResToolbox"
21
+
22
+ [project.scripts]
23
+ pyrestoolbox-mcp = "pyrestoolbox_mcp.server:main"
24
+
25
+ [tool.setuptools.packages.find]
26
+ include = ["pyrestoolbox_mcp*"]
@@ -0,0 +1,3 @@
1
+ """MCP server exposing the pyrestoolbox reservoir engineering library."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,50 @@
1
+ """Convert pyrestoolbox return values to JSON-serializable structures."""
2
+
3
+ import dataclasses
4
+ import math
5
+ from enum import Enum
6
+
7
+
8
+ def to_jsonable(obj):
9
+ """Recursively convert obj to JSON-serializable Python primitives.
10
+
11
+ numpy scalars/arrays, pandas DataFrames/Series, dataclasses, Enums and
12
+ nested containers are handled. Non-finite floats become None (JSON has
13
+ no NaN/inf).
14
+ """
15
+ if obj is None or isinstance(obj, (bool, str)):
16
+ return obj
17
+ if isinstance(obj, int):
18
+ return int(obj)
19
+ if isinstance(obj, float): # np.float64 subclasses float - cast to plain float
20
+ return float(obj) if math.isfinite(obj) else None
21
+ if isinstance(obj, Enum):
22
+ return obj.name
23
+ if dataclasses.is_dataclass(obj) and not isinstance(obj, type):
24
+ return {f.name: to_jsonable(getattr(obj, f.name)) for f in dataclasses.fields(obj)}
25
+ # numpy
26
+ try:
27
+ import numpy as np
28
+ if isinstance(obj, np.generic):
29
+ return to_jsonable(obj.item())
30
+ if isinstance(obj, np.ndarray):
31
+ return [to_jsonable(v) for v in obj.tolist()]
32
+ except ImportError:
33
+ pass
34
+ # pandas
35
+ try:
36
+ import pandas as pd
37
+ if isinstance(obj, pd.DataFrame):
38
+ return {
39
+ "columns": [str(c) for c in obj.columns],
40
+ "records": to_jsonable(obj.to_dict(orient="records")),
41
+ }
42
+ if isinstance(obj, pd.Series):
43
+ return to_jsonable(obj.tolist())
44
+ except ImportError:
45
+ pass
46
+ if isinstance(obj, dict):
47
+ return {str(k): to_jsonable(v) for k, v in obj.items()}
48
+ if isinstance(obj, (list, tuple, set)):
49
+ return [to_jsonable(v) for v in obj]
50
+ return str(obj)