Skip to main content

commovision

The Python client and command line for the CommoVision oil and gas data API. It wraps the REST contract at api.commovision.com: keyed requests, cursor pagination, CSV and DataFrame loading, bulk extracts, and the change feed. The full endpoint reference lives at https://api.commovision.com/docs.

Install

pip install commovision

DataFrame loading is optional: pip install "commovision[polars]" or pip install "commovision[pandas]".

Quickstart

Three steps from a key to data.

  1. Create a key in the portal at app.commovision.com under Account & settings, API keys, and put it in the COMMOVISION_API_KEY environment variable. The key is shown once: store it in a secrets manager or an environment variable, never in code.

  2. Confirm the key works and read what it can access. A result confirms the key; entitlements lists what your plan grants:

    import commovision
    
    client = commovision.Client()
    print(client.me()["entitlements"])
    
  3. Make your first data call. rows walks pages for you; filters pass through exactly as the reference spells them:

    for well in client.rows("wells", state_province="Texas", limit=10):
        print(well["well_id"], well["well_name"])
    

limit is the most rows you want IN TOTAL, across every page. Leave it unset and the walk reads the whole selection, which on a wide filter is a large pull: one request per page, and every row counts against your plan's budget. page_size sets how many rows one request asks for; leave it unset and the server chooses.

DataFrames

wells = client.frame(
    "wells",
    state_province="Texas",
    basin="Permian Basin",
    trajectory="horizontal",
    limit=5000,
)  # polars; client.df(...) returns pandas

One well's monthly series, by its opaque well_id:

series = client.frame(f"wells/{wells['well_id'][0]}/production", month="2020-01..")

Treat well_id and every other id as an opaque string.

Whole-selection CSV

Register routes stream your whole filtered selection as one download, without paging. The server refuses up front when the selection does not fit your remaining budget, so a download is never cut short for budget:

client.export_csv("permits", "tx_permits.csv", state_province="Texas")

A download writes a temporary file beside its destination and renames over it, so the destination is replaced rather than written through. A path that exists and is not a regular file is refused for that reason: -o /dev/null would replace the null device rather than discard the bytes. Name a file, or a path that does not exist yet.

One consequence of that, worth knowing before it surprises you: a destination that is a symlink to a regular file is replaced by a regular file, so the file it pointed at is left untouched and stops being updated. If you keep something like latest.parquet as a link into a shared directory, download to the real path and update the link yourself. Resolving the link and writing through it would be the worse behaviour, because a partly written file would then be visible to everything reading the shared copy.

Bulk extracts and the change feed

For a whole table, download a prebuilt extract, then keep it current from the change feed instead of re-downloading:

catalog = client.extracts()
record = client.download_extract("tx", "well_production", "tx_production.parquet")

feed = client.changes("tx", "well_production", from_version=record["version"])
for page in feed:
    apply_upserts_and_deletes(page.rows)  # your upsert by key, delete by key
    store(feed.cursor)                    # the resume point

A stored cursor resumes for 60 days. One past that raises commovision.CursorExpired, whose resync_extract names the extract to reload before starting the feed again from its version.

Command line

commovision wells --state-province Texas --limit 1000 --csv > tx_wells.csv
commovision wells --state-province Texas --all -o tx_wells.csv
commovision me
commovision extract tx well_production -o tx_production.parquet
commovision changes tx well_production --from-version 3 --state-file tx.cursor
commovision get /oil-gas/v1/freshness

Filter flags pass through as query parameters, so the command line serves every filter the API serves; an unknown one is refused by the server with the parameter named. --limit is the most rows in total and --page-size the rows per request; --all writes the whole selection and takes neither. Pass the key in COMMOVISION_API_KEY rather than --key, which is visible to every user of the machine and lands in shell history and CI logs.

Exit codes a script can branch on:

Code Means
0 done
2 a usage error, or a request the server refused
3 the change cursor expired: reload the extract named on stderr
4 over quota

Pacing and errors

Your plan states a rolling 24-hour row ceiling, and on some plans a monthly allowance; every data response reports both in its headers. The client sleeps out a short 429 or 503 wait on its own and retries. A wait longer than max_retry_wait (120 seconds by default) is not slept: the client raises instead, so a monthly refusal surfaces as an exception rather than a weeks-long sleep.

Every failure the API itself reports raises commovision.APIError, carrying the API's error body: branch on error.code (a stable identifier such as invalid-parameter), read error.retry_after where the answer named one, and quote error.request_id when you write to us at https://commovision.com/contact/. Two subclasses mark the cases a script usually handles on its own:

Exception Raised for
commovision.QuotaExceeded a 429: a row quota, or the per-account in-flight bound
commovision.CursorExpired a 410 on the change feed; resync_extract names the extract to reload
commovision.ChecksumMismatch a downloaded extract that does not match the sha256 its issuance stated: download it again rather than retrying the issuance
commovision.CommoVisionError the client's own refusals: no key, a missing optional extra, a parameter a walk sets itself

The first two are APIError; all four are commovision.CommoVisionError, so one except commovision.CommoVisionError catches everything this package raises.

One name to know when you set page_size: it rides as the request's own limit, so a value above a route's maximum comes back as a 400 naming limit. Leaving page_size unset lets the server choose, which is the right default; set it when you would rather make fewer, larger requests.

Versioning

This package follows the API's own compatibility promise rather than an internal one, because people depend on it from outside:

  • Additive change ships freely in minor and patch releases: new methods, new optional parameters, new fields in returned data. Write your code to ignore fields it does not recognize.
  • A breaking change to this package ships only as a new major version, announced in the changelog below.
  • The API itself versions by namespace: a breaking API change ships as a new namespace and the prior one keeps working for at least six months after the announcement (reference, "Versioning").

License

MIT. Keep the copyright notice with the code and there is nothing else to observe; the full text ships in the package as LICENSE.

Changelog

  • 0.1.0: first release. Keyed requests with pacing, cursor pagination, CSV and DataFrame loading, whole-selection export, bulk extract download with checksum verification, the change feed, and the command line.

Metadata

Release files for commovision 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for commovision 0.1.0
File Size Uploaded
commovision-0.1.0.tar.gz 24.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for commovision 0.1.0
File Interpreter ABI Platform
commovision-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 47.3 kB

Release files / commovision-0.1.0.tar.gz

Download URL commovision-0.1.0.tar.gz
Size 24.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c59cb021a216db0ac43bbedf4e4cb336b65b390b40b001547f78864e14e3186b
BLAKE2b-256 checksum
How to use checksums
361fb6372f1f57511900b614b11070b351a7c69fd13d444a912bea5bec89a5e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / commovision-0.1.0-py3-none-any.whl

Download URL commovision-0.1.0-py3-none-any.whl
Size 22.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d838ba89878b2e760e122f55a6eb294bdc3e116bab11dc35daa8203d34837922
BLAKE2b-256 checksum
How to use checksums
82ac1eeb33692287131543ac6b45c3169ccf4b5fb3fd4da04dca54d8e52377d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page