Write or upload a Python module on Petrophysics.io, save a version, and publish selected functions for remote callers. A colleague can call those functions from Python in VS Code and receive JSON results. The implementation stays on the Python backend; the public client downloads only the small HTTP wrapper.
This requires deploying the new v24 Python service. Updating the static website alone does not start a Python API. Use the actual service URL until https://api.petrophysics.io has been configured and verified.
The workflow
- Open Hosted libraries. The public catalogue lists libraries available to you.
- In Create & manage, enter the Owner password and choose Sign in using the backend's
LIBRARY_ADMIN_PASSWORD. This password grants source-management access; give colleagues consumer API keys instead. - Choose Open .py to load a file or New blank library to write code. Set Library ID, Title, Description and comma-separated Exported function names. Leaving exported names blank infers public top-level functions. Explicitly choose names when some functions are intended as internal helpers.
- Choose Save to server to save a draft while developing, or enable Publish this library for external calls. Every server save creates a numbered version. Loading a file or typing does not upload anything automatically. Save draft .py ↓ downloads a local copy without publishing it.
- Set Caller access to public for functions anyone may call, or key for colleagues you authorize. Copy a newly generated consumer key into a secure password manager when it is shown. Rotate API key replaces the key and invalidates the previous key. Do not put it in the website's JavaScript, screenshots or a public repository.
- In Try a function, supply positional args/keyword args as JSON, the published version if required, and a caller key for key access. Then use the downloadable client below from ordinary Python. Give colleagues the library ID, version and selected function signatures.
Only trusted owners upload source. v24 is a service for your own reviewed libraries, with execution limits and source checks; it is not a secure environment for accepting arbitrary code from strangers. Unsupported source is rejected. A library that depends on a local filesystem, shell, subprocesses or network access must be adapted before publication.
Your first remote call
Download petrophysics_client.py and put it in the same folder as your Python script. There is no pip install step and no mandatory NumPy dependency on the caller's computer.
from petrophysics_client import Client
api = Client("https://api.petrophysics.io") # your deployed backend URL
demo = api.library("demo", version=1)
vsh = demo.vsh([20, 40, 60, 80, 100], gr_min=20, gr_max=100)
print(vsh)
# [0.0, 0.25, 0.5, 0.75, 1.0]
phi = demo.density_porosity([2.30, 2.40, 2.50])
sw = demo.archie_sw([15, 10, 5], phi, rw=0.1)
print(phi)
print(sw)
The backend seeds the public demo library at version 1. These simple demonstrations assume consistent units: GR in API, densities in g/cm³, porosity/Vsh/Sw as fractions, and Rw/Rt in the same resistivity unit. They are examples, not a complete formation interpretation.
| Function | Parameters | Return |
|---|---|---|
vsh | gr, gr_min=20, gr_max=100 | Linear GR shale volume clipped to 0–1 |
density_porosity | rhob, rho_matrix=2.65, rho_fluid=1.0 | Raw density porosity: (rho_matrix - rhob) / (rho_matrix - rho_fluid) |
archie_sw | rt, porosity, rw=0.1, a=1, m=2, n=2 | Archie water saturation clipped to 0–1 |
Both scalars and arrays are accepted by the demo functions. NumPy arrays and scalars in client inputs are converted to ordinary JSON values automatically. Results are JSON values: arrays return Python lists. Use np.asarray(result) in the caller if you need a NumPy array.
Publish your own function
This module does not need a LAS file or the browser's well object:
import numpy as np
def effective_porosity(total_porosity, shale_volume, shale_porosity=0.1):
phi = np.asarray(total_porosity, dtype=float)
vsh = np.asarray(shale_volume, dtype=float)
result = np.clip(phi - vsh * shale_porosity, 0.0, 1.0)
return result.tolist()
Save it under slug my-petrophysics, export effective_porosity, and publish it with the chosen access setting. Send the caller the assigned version number. Use arrays of matching length; server functions remain responsible for validating their own scientific inputs.
import os
from petrophysics_client import Client
api = Client(
"https://api.petrophysics.io",
api_key=os.environ["PIO_API_KEY"], # omit for public libraries
)
mine = api.library("my-petrophysics", version=1)
result = mine.effective_porosity([0.25, 0.20], [0.10, 0.40])
print(result) # [0.24, 0.16]
The colleague can read the wrapper and your public function metadata. They do not receive the saved module's implementation. This reduces direct source copying; exposing results can still allow an algorithm to be inferred, and this service does not provide a legal or absolute technical guarantee against copying.
Client options and errors
from petrophysics_client import Client, RemoteError
api = Client("https://api.petrophysics.io", timeout=30)
print(api.catalog())
try:
result = api.call("demo", "vsh", [20, 60, 100], version=1,
gr_min=20, gr_max=100)
except RemoteError as exc:
print(exc.error_code, exc.status, str(exc))
Client.call(slug, function, *args, version=None, **kwargs) and api.library(slug, version=None).function(...) return the result, rather than the HTTP envelope. Version is a positive integer. Omit it for the latest published version; pin it to make saved workflows reproducible. A historical version must have been published when saved, and the current library must remain published. Current access permissions and keys apply to historical versions too.
NaN/infinity, circular objects and unsupported types are rejected before a request. Represent missing samples with None and make your function handle them. The backend enforces input, output and execution limits, and returns controlled errors. The client preserves the backend's error code, message and optional details without printing a raw HTML error page. An HTTP status is available as exc.status; a connection error has None.
Default backend limits are 256 KiB of source, 1 MiB per input request, 1 MiB per output result, a 20-second execution timeout, a 256 MiB worker virtual-address-space limit and one concurrent call. An owner can configure execution timeout, memory, concurrency and rate limits in the backend environment; /health reports configured limits. For larger scientific calculations, upgrade the service memory plan and worker limit together; the worker limit does not reserve physical RAM. Split large calculations into batches rather than sending a complete LAS file as an oversized JSON request.
The client requires HTTPS outside localhost testing and does not follow redirects or retry calls. If a call times out, the server may already have executed it. Check the URL and use the intended hostname directly rather than relying on a redirect.
HTTP interface for other clients
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/libraries | Published library metadata, including libraries whose calls require a key |
POST | /api/v1/libraries/{slug}/functions/{function}/call | Execute an exported function |
GET | /health | Service health and configuration |
Send Content-Type: application/json. A key-protected library needs the X-API-Key header. A request can use positional arguments, keyword arguments or both:
{"args": [[20, 60, 100]], "kwargs": {"gr_min": 20, "gr_max": 100}, "version": 1}
The success response wraps the result with its identity:
{"result": [0.0, 0.5, 1.0], "library": "demo", "function": "vsh", "version": 1}
Errors use {"error":{"code":"...","message":"..."}} with an appropriate HTTP status. Public API routes do not return implementation source. Save, source access and key management require owner authentication.
Browser packages and hosted dependencies
The existing v23 Python libraries run in each user's browser via Pyodide. Hosted functions run in the separate Python service. Loading a browser package does not install it on the server. The v24 backend includes NumPy, SciPy and pandas; further supported dependencies must be added to library-server/requirements.txt, reviewed and deployed before importing them in a hosted library. Do not try to install dependencies from uploaded source.
Existing log-viewing and browser Python workflows keep their normal local behavior. A remote call transmits the supplied JSON data to your backend for processing. Send only arrays/parameters needed by that function; users should make that data-sharing decision explicitly.
Deployment
Follow RENDER_LIBRARY_V24.md for the exact GitHub and Render setup. The static site uses node scripts/build-static.mjs and publishes dist. The Python service uses root directory library-server and needs a persistent disk. Never store a private business module in the public/static directory or GitHub repository; save it through the authenticated owner workspace onto backend storage.
The distributed files are implementation packages; they are not proof that the live API has already been deployed. The catalogue and calls become available when the Python service is running and js/library-config.js points at its verified URL.