Run a Python curve application
Bounded pilot, qualified 24 September 2026. One LAS value curve, one portable LAS output. This is a reference client, not a stable SDK or hosted Python service. SQL, OSDU and native application writers are not part of this workflow.
Before you start
Section titled “Before you start”Your deployment needs browser identity, managed sources and the application routes enabled. Sign in as a project administrator with an authorized LAS file source. This initial workflow uses the same account for source selection, binding and execution; selecting a source never grants another account access. A deployment administrator provisions the connection first; see manual source setup.
- Open Connections → Data sources. Expand your LAS connection and inspect its asset. Review the source context and add it to the project. Unknown depth reference remains unknown.
- Open Connections → Applications → Configure application.
- Name the application, select the LAS source and a value curve such as
GR. The depth index is not an editable input curve. - Choose Use source selection policy, or pin the currently selected revision. A pin does not retain old file contents. Replacing a file can make that revision unavailable.
- Leave the output as Portable LAS and save. Open your new binding to obtain its ID and a command example.
- Use browser-authorized Python access below if your deployment enables it. Developer → Application access lists pending and approved applications and lets you revoke them. Temporary manual delegates remain available as a fallback.
Run locally
Section titled “Run locally”Download both the curve client and application login helper into the same folder. They use Python 3.10+ and only the standard library; no internal packages or SDK installation.
python3 application_access.py login --url https://YOUR-WORKSPACE \ --project YOUR-PROJECT --write- The browser opens your deployment’s identity provider. Sign in with the account that owns the source selection and application binding.
- Approve the provider’s device request. Python then opens Application access in Workspace. Sign into Workspace if needed; it returns to that request.
- Verify the account, project, permissions and confirmation code against your terminal. Check the confirmation box and choose Approve application.
- Return to Python. No bearer secret is copied. Then run:
python3 curve_application.py --url https://YOUR-WORKSPACE \ --project YOUR-PROJECT --binding YOUR-BINDING \ --start 100 --stop 103 --offset 2 --output my-resultUse --no-browser on the login command for an SSH terminal; open its displayed URLs
on a browser that can reach the same deployment. The short device/confirmation codes
are not bearer credentials. Only approve a request you started: script labels are not
verified publisher identities.
The helper stores access and refresh credentials in an owner-only file at
~/.config/ophiolite/application.json. This is not encrypted keychain storage.
For separate installations/projects, pass --credentials /PRIVATE/PATH.json before
login, status or logout, and pass that same option to the curve client.
python3 application_access.py statuspython3 application_access.py logoutLogout revokes the application grant, asks the provider to revoke its refresh token, and removes the local file. If remote revocation fails, the CLI reports it; use Workspace Developer or provider account management to finish revocation. Revocation stops subsequent requests, not an already-authorized operation or downloaded copies.
Bounded online-session pilot, qualified with Keycloak. Access tokens refresh automatically while the provider session is valid. The qualification configuration uses five-minute tokens, ten-minute idle expiry and a thirty-minute session maximum. After session expiry, run browser login and approve again. Consent expires after at most seven days but never extends provider-session validity. This is not an unattended service identity. Browser logout and application revocation are separate actions. A different self-registered account—even with a familiar email—does not inherit demo or project access. Ask your administrator for explicit account enrollment and project permissions. The current application profile requires project administrator access.
Manual fallback: create a read/write delegate in Developer, set OPHIOLITE_TOKEN
privately using a hidden terminal prompt, and run the curve command without an explicit
credentials file. That delegate lasts five minutes and requires the parent browser
session. Remove the environment variable before using browser-authorized access.
Use your actual Workspace origin, project and binding. HTTP is permitted only for loopback demos. The interval is inclusive, in the input depth unit; the offset uses the curve’s unit. These numbers fit the synthetic fixture below, not every real log.
The client reads an exact input revision and its original LAS, calculates an interval offset locally, and publishes changed samples. It skips missing samples, preserves the axis and other curves, and never edits the source file. At most 1,000 changed samples per publication; choose a bounded interval for a long log. A zero offset or an interval containing only missing values produces no result.
Return to your binding in Workspace and refresh Runs. Download the output and receipt and inspect them locally. Portable results appear in the binding’s Runs list, not as new Data catalogue assets or Activity operations. Following an input does not run Python; publishing does not apply data to another application. Review is not compulsory.
What the result means
Section titled “What the result means”The output directory contains original.las, input.json, changes.json, run.json, result.las and receipt.json. Preserve this directory for retries. A receipt records the exact input, binding version, output checksum and publishing account. The application version and parameters are script-declared; the server did not observe or certify the calculation.
Normalized samples use JSON null for missingness. A genuine 0 remains zero. The original LAS retains its declared NULL sentinel. The derived LAS writes missing samples with the LAS NULL marker; it does not fill gaps. Reader/mapping versions and parsing policy accompany the input and run. Unknown units or datum are never inferred from project defaults.
For a synthetic input with depths [100,101,102,103,104] and GR [0,10,null,30,40], the example produces [2,12,null,32,40]. Independent verification, using optional lasio and numpy:
import hashlib, json, lasio, numpy as npfrom pathlib import Pathfolder = Path("my-result")receipt = json.loads((folder / "receipt.json").read_text())assert hashlib.sha256((folder / "result.las").read_bytes()).hexdigest() == receipt["receipt"]["manifest"]["sha256"]log = lasio.read(folder / "result.las")assert np.array_equal(log.index, [100,101,102,103,104])assert np.array_equal(log["GR"], [2,12,np.nan,32,40], equal_nan=True)The fixed assertions are for the synthetic fixture only. The qualification also exercised a downloaded HON-GT-01 NLOG log with 32,401 samples and a bounded correction; this does not qualify every LAS variant.
Recovery and limits
Section titled “Recovery and limits”- Expired provider session or revoked grant: repeat browser login and approve a new request, then repeat the same curve command and output directory. Existing manual delegates still require their parent browser session. Revoke obsolete grants in Developer.
- Interrupted publication: repeat the identical command. Saved changes allow receipt recovery after commit even if the original file subsequently changes, provided source configuration and permissions remain valid. Different output for the same run is refused.
- Source changed before commit: refresh and review the source selection; update a pinned binding if appropriate. Start with a new output directory. Old exact file reads are not guaranteed.
- Binding changed: reload its configuration and start a new output directory. Earlier runs keep their original configuration.
- No eligible LAS input: register and select a supported LAS source under the same account. An OSDU Parquet representation is not a LAS input for this profile.
- Capacity: 100 bindings and 100 runs per account/project, and 100 lifetime drafts shared with manual editing. Drafts are created only at publication. This pilot does not offer automatic archival/reset.
Single gateway process; up to 100,000 samples and 64 curves; no axis or unit edits. Transfers preserve meaning; applications may deliberately alter values or missingness through explicit changed samples. Browser SQL-well subscriptions, Python curve publication and native-host integration remain separately qualified capabilities.
See the application HTTP contract.
