Python SDK

There are two Python clients, both generated from — or tracking — the same operation registry, so neither can drift from the live API:

  • geopera — a friendly, hand-curated client with high-level namespaces (client.catalog, client.orders, client.processing, client.billing). Start here for application code.
  • geopera_kernel — a fully generated, low-level client with one typed method per operation. Use it when you want the complete operation surface, exactly typed, with no curation.

Install

bash
pip install geopera-py

Authenticate

python
import geopera

# Machine-to-machine (servers, pipelines) — recommended
client = geopera.Client.from_api_key("gp_live_...")

# Or via your Geopera login (interactive scripts)
client = geopera.Client.from_password("[email protected]", "password")

from_api_key exchanges the key for short-lived JWTs and refreshes them for you, so you don’t manage token lifetimes. from_client_credentials is also available for the OIDC client-credentials grant.

Search the catalog

python
results = client.catalog.search(
    host="earthsearch-aws",
    collections=["sentinel-2-l2a"],
    bbox=[151.0, -34.0, 152.0, -33.0],
    datetime_range="2024-01-01T00:00:00Z/2024-12-31T23:59:59Z",
    cloud_cover_lte=20,
    limit=25,
)
for feature in results.features:
    print(feature.id, feature.properties["datetime"])

Preview a price and place an order

python
# Server-authoritative price preview (a read — nothing is charged)
quote = client.orders.estimate(
    data_product="phr",
    feature_collection=fc,   # a GeoJSON FeatureCollection over your AOI
)
print(quote["total_credits"], quote["total_aud"])

# Place the order
order = client.orders.create(
    workspace_id="your-project-id",
    data_product="phr",
    display_name="Sydney harbour archive",
    feature_collection=fc,
    params={"id": "scene-abc"},
    tags=["production"],
)

# Track to a terminal state
fetched = client.orders.get(order["results"][0]["id"])
print(fetched.status)

Other order methods: client.orders.list(...), client.orders.update_tags(id, tags), client.orders.cancel(id), and client.orders.schema(data_product_id) to introspect a product’s parameters.

Processing

python
# Discover available processes and their cost
processes = client.processing.list_processes()
cost = client.processing.cost(process_id, inputs={...})

# Run one
job = client.processing.execute(
    process_id,
    workspace_id="your-project-id",
    inputs={"source_item_id": "it_3a9c...", "...": "..."},
)

# Track it
status = client.processing.get_job(job["id"])

Billing

python
balance = client.billing.balance()
print(balance.credits)

# Attach a card via Stripe SetupIntent, then top up
intent = client.billing.setup_intent()        # confirm client-side with Stripe.js
result = client.billing.topup(credits=50000)   # charges the default card

# Automate it
client.billing.set_auto_topup(
    enabled=True,
    threshold_credits=5000,
    topup_amount_credits=50000,
)

If a top-up needs 3-D Secure, topup surfaces the client_secret to complete the challenge — see the 3-D Secure retry.

Webhooks (event subscriptions)

Subscribe to platform events and stop polling. Each delivery is an HTTP POST signed with an HMAC-SHA256 X-Geopera-Signature header so you can verify it came from Geopera. Discover the full event catalogue with event_types().

python
sub = client.webhooks.subscribe(
    url="https://your-app.example.com/hooks/geopera",
    events=["order.fulfilled", "job.completed", "credits.low_balance"],
)
client.webhooks.list()
client.webhooks.event_types()   # discover available event types

On your receiver, verify the X-Geopera-Signature header against the subscription secret before trusting a delivery:

python
import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header or "")

Delivery is durable and at-least-once with retry/backoff, so make your handler idempotent (dedupe on X-Geopera-Event-ID). See the Webhooks guide for the full event catalogue, the delivery headers, and delivery semantics.

The generated low-level client

When you want the complete, exactly-typed surface — every operation, every input/output model — use geopera_kernel. It’s a standard openapi-python-client package: one module per operation plus a model for each input and output.

python
from geopera_kernel import AuthenticatedClient
from geopera_kernel.api.kernel_ops import items_search_org
from geopera_kernel.models import OrgItemSearchInput

client = AuthenticatedClient(base_url="https://api.geopera.com", token="<jwt>")
resp = items_search_org.sync_detailed(
    client=client,
    body=OrgItemSearchInput(limit=5),
)
print(resp.parsed)

Because it’s generated from the kernel’s reflected OpenAPI, adding an operation to the platform adds a typed method here on the next regeneration — no hand-maintained types.

Errors

Both clients raise on non-2xx responses, surfacing the application/problem+json body (status, title, detail). Handle 402 for payment problems and 409/422 for conflicts and validation as described in Errors.