nativegate
← Blog

Exposing petroleum engineering models through Python

The day-to-day users of a petroleum model are rarely the engineers who maintain it: they're reservoir engineers in notebooks, workflows calling property math mid-simulation, ML pipelines needing fluid properties at scale. This post is about the interface those consumers want — and the engineering realities of the source code that constrain it.

What petroleum models look like from the outside

Typical legacy decks of this class: a small handful of configuration-like entry points (initialize a fluid at equivalent depths, set a reservoir temperature) followed by question-like routines (bubble point at this pressure? viscosity of this oil? relative permeability? Peaceman well index for this geometry?). The calls are cheap; the semantics are the session: state persists between them.

What the Python surface looks like

Exposed through nativegate, the same routines become an importable package where a notebook does:

the caller's view
>>> import petro_api>>> results = petro_api.exposed_routine(pressure, temperature, composition)

Typed NumPy arguments in, typed results out. No input-deck editing, no file intermediates, no Fortran knowledge required — while underneath, the same compiled correlations answer, verified against the golden record.

The engineering realities that shape the API

  • State is a session, not a singleton. COMMON-block state means configure-then-query. Sequential calls per session; sessions per process. Document it, or concurrency will invent a worse version.
  • Units are the API. The discipline's units conventions — pressures, depths, densities — are embedded in the routines. Exposing them unchanged is safer than abstracting them: the exposed surface should not add a second unit system to a modernization.
  • Regression is the feature. The listeners of this API plan wells. The recorded baseline is what makes every change to the surface — new wrapper, new compiler — the same meaning of "unchanged."

Over HTTP, at the second consumer

The same surface becomes HTTP the moment someone other than the authoring team needs it: operations engineers calling from web tools, or another simulator's preprocessor. The generated service adds the API-key auth, rate limiting, and health probes, and carries the same locked-for-correctness semantics — one native call at a time per process, so replicas, not workers, carry the concurrency.

The point worth repeating from each of the petroleum posts: nothing here required rewriting the correlations. The modernized part is who can call them.

The worked example → Related: the petroleum case