Skip to main content

python-oda

Python version Poetry Ruff mypy

python-oda is a Python client for Ocean Data Access (ODA), eOdyn's REST API.
It lets you search and download oceanographic data through a filterable, typed API.

Features

  • Command-line interface — browse and download products, datasets, documents and reports from the terminal with the oda-cli command, no Python required
  • High-level, typed API — browse products, datasets, documents and reports through a single entry point (Oda), with results returned as typed Pydantic models
  • Flexible authentication — authenticate with a username/password, an existing JWT (access + refresh token), or OAuth2 client credentials
  • Automatic token handling — access tokens are refreshed transparently, and API calls are retried once with a fresh token if they fail due to an expired/invalid token
  • Lazy, filterable pagination — search products, datasets, documents and reports with server-side filtering and ordering, iterating results lazily as pages are fetched
  • Streaming downloads — download documents and reports as a byte stream, with an optional progress bar (powered by tqdm) or a custom progress tracker
  • Concurrent downloads — download multiple documents or reports in parallel across a thread pool, with a configurable number of workers (5 by default)
  • Built-in data readers — convert downloaded documents directly into pandas, polars or xarray objects, or plug in your own custom reader
  • Fully typed with annotations and checked with mypy, PEP561 compatible

Installation

pip install python-oda

Optional extras are available for the built-in data readers: python-oda[pandas], python-oda[polars] and python-oda[xarray].

Usage

Authentication

oda supports three authentication methods.
Credentials can also be provided via the ODA_USERNAME/ODA_PASSWORD environment variables, in which case Oda() can be instantiated without an explicit authentication argument.

from oda import Oda
from oda.core.authentication import AuthClient, AuthJWT, AuthUser

# Username / password
oda = Oda(authentication=AuthUser(username="my-user", password="my-password"))

# Existing JWT (access token, optionally with a refresh token)
oda = Oda(authentication=AuthJWT(access_token="...", refresh_token="..."))

# OAuth2 client credentials
oda = Oda(authentication=AuthClient(client_id="my-client", client_secret="my-secret"))

Browsing products and datasets

# Find products matching a filter
for product in oda.products.find(provider="eOdyn", order_by="+name"):
    print(product)

# Find datasets matching a filter
for dataset in oda.datasets.find(type="currents", tags_in=["OS"]):
    print(dataset)

Finding and downloading documents

# List documents in a dataset
for document in oda.documents.find(dataset_name="altimetry-sealevel-l3-swot"):
    print(document.name, document.start_datetime, document.size)

# Download all matching documents to disk, with a progress bar
oda.documents.download(dataset_name="altimetry-sealevel-l3-swot", output_path="./downloads")

# Download concurrently across a thread pool (per-file byte progress is disabled beyond 1 worker)
oda.documents.download(dataset_name="altimetry-sealevel-l3-swot", output_path="./downloads", workers=4)

# Or download a single document into memory and load it directly as a DataFrame
document = next(iter(oda.documents.find(dataset_name="altimetry-sealevel-l3-swot", name="SWOT_L3_LR_SSH_Expert_outre-mer_053_464_20260726T173752_20260726T182918_v3.0.nc")))
df = document.download().to_pandas()  # also available: .to_polars(), .to_xarray()

# Filter documents by date range
from datetime import datetime

for document in oda.documents.find(
    dataset_name="altimetry-sealevel-l3-swot",
    date__gte=datetime(2026, 7, 1),
    date__lte=datetime(2026, 7, 26),
):
    print(document.name, document.start_datetime)

Finding and downloading reports

for report in oda.reports.find(dataset_name="altimetry-sealevel-l3-swot", document_name="SWOT_L3_LR_SSH_Expert_outre-mer_053_464_20260726T173752_20260726T182918_v3.0.nc"):
    print(report)

oda.reports.download(
    dataset_name="altimetry-sealevel-l3-swot",
    document_name="SWOT_L3_LR_SSH_Expert_outre-mer_053_464_20260726T173752_20260726T182918_v3.0.nc",
    output_path="./downloads",
)

Command-line interface

python-oda also ships a CLI, installed as the oda-cli command, for browsing and downloading products, datasets, documents and reports without writing any Python.

The CLI is configured entirely through environment variables:

Variable Description
ODA_USERNAME, ODA_PASSWORD Credentials used to authenticate (required)
ODA_API_URL ODA API base URL (default: https://oda.eodyn.com)
AUTH_HOST URL of the authentication service (default: auto-discovered from ODA_API_URL)

Run oda-cli --help to see this reminder at any time.

# Check that your credentials are valid
oda-cli whoami

# Browse
oda-cli products find --provider eOdyn
oda-cli datasets find --type currents --tag OS
oda-cli documents find --dataset-name altimetry-sealevel-l3-swot --date-gte 2026-07-01
oda-cli reports find --dataset-name altimetry-sealevel-l3-swot --document-name my-document

# Download
oda-cli documents download --dataset-name altimetry-sealevel-l3-swot --output-path ./downloads
oda-cli reports download --dataset-name altimetry-sealevel-l3-swot --document-name my-document

# Output as JSON lines instead of a table (e.g. for piping into jq)
oda-cli documents find --dataset-name altimetry-sealevel-l3-swot --json

Run oda-cli --help or oda-cli <command> --help for the full list of options.

Contact

For questions or support, contact support-it@eodyn.com.

Metadata

Release files for python-oda 0.2.1

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

Built distribution (wheel)

Table of built distributions (wheels) for python-oda 0.2.1
File Interpreter ABI Platform
python_oda-0.2.1-py3-none-any.whl Python 3 none any Details

Release files / python_oda-0.2.1-py3-none-any.whl

Download URL python_oda-0.2.1-py3-none-any.whl
Size 157.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39cfbcebe2e2d7a04201703953203cde6545a591dcff999645cd266b2ab19ffd
BLAKE2b-256 checksum
How to use checksums
4f724e3f195d63370dbab20836f5c8c352ed6a61f377b4b20b2cec3131810154
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.13.5 Linux/5.15.0-185-generic

Release history Release notifications | RSS feed

0.2.2

1 release file

This release

0.2.1 This release

1 release file

0.2.0

1 release file

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