Skip to main content

Official Python stub client for the geog.ai Spatial Intelligence API.

Project description

geog-ai (Python)

Stub client for the geog.ai Spatial Intelligence API. Generated from openapi.yaml (v1). All 28 documented endpoints are exposed as methods on a single GeogClient.

Stub status. Method signatures cover every documented path and method. Request and response payloads are plain dicts — refine to typed models with pydantic or regenerate from the OpenAPI spec when stricter types are needed.

Install

pip install geog-ai

Requires Python ≥ 3.9 and requests.

Usage

import os
from geog_ai import GeogClient

geog = GeogClient(api_key=os.environ["GEOG_API_KEY"])

# 1. Resolve spatial context for a registered device
ctx = geog.context(device_id="sensor_h2s_023")

# 2. Kick off an async plume simulation
job = geog.simulate_plume({
    "source": {
        "lat": 31.9642, "lon": -99.9035, "alt_m": 545,
        "emission_rate_gs": 2.4, "stack_height_m": 12,
    },
    "duration_min": 60,
    "tier": 1,
    "species": "H2S",
})

# 3. Wait for completion (polls /jobs/{id})
result = geog.wait_for_job(job["job"]["id"])
print(result["result"])

Async-job polling (typed result)

/simulate/*, /rf/mesh/viability, /rf/optimize/placement and /optimize/* return the same AsyncJobAccepted envelope (HTTP 202) — just an acknowledgement with a job.id. The actual payload lands at GET /jobs/{job_id}, typed as JobResponse[TResult]. wait_for_job returns JobResponse[Any]; cast to your generic so type-checkers (mypy/pyright) treat done["result"] as your concrete shape:

import os
from typing import List, TypedDict, cast
from geog_ai import GeogClient
from geog_ai.types import JobResponse


class PlumeContour(TypedDict):
    ppb: float
    geometry: dict


class PlumeResult(TypedDict):
    contours: List[PlumeContour]
    peak_ppb: float
    impacted_receptor_ids: List[str]


geog = GeogClient(api_key=os.environ["GEOG_API_KEY"])

# 1. Submit — 202 AsyncJobAccepted, no "result" yet
accepted = geog.simulate_plume({...})

# 2. Poll until terminal state and cast to your typed envelope
done = cast(
    JobResponse[PlumeResult],
    geog.wait_for_job(accepted["job"]["id"], interval=2.0, timeout=300),
)

# 3. Narrow on status before reading "result"
if done["job"]["status"] == "complete" and done.get("result"):
    result: PlumeResult = done["result"]
    print(result["peak_ppb"], result["impacted_receptor_ids"])
else:
    raise RuntimeError(f"Job {accepted['job']['id']} failed")

# One-shot snapshot (no polling loop):
snapshot = cast(JobResponse[PlumeResult], geog.job(accepted["job"]["id"]))

Swap PlumeResult for FloodResult, RFCoverageResult, MeshViabilityResult, NodePlacementResult, etc. — the SDK shape is the same; only your generic changes per endpoint.

Two envelopes, not one. AsyncJobAccepted (returned immediately by the submit call) only carries {"ok", "job": {"id", "status", ...}} — no "result". The eventual JobResponse[TResult] from GET /jobs/{id} only populates "result" when job.status == "complete"; on "failed" inspect job["error"] / meta.

Errors

Non-2xx responses raise geog_ai.GeogApiError with status, code, message, optional details, and request_id attributes.

Regenerating types from the spec

The primitive request/response shapes (Location, WindVector, SpatialState, AsyncJobResponse, etc.) live in geog_ai/_openapi_gen.py, which is auto-generated from QHPA/marketing/geog/docs/openapi.yaml by datamodel-code-generator. The hand-written geog_ai/types.py re-exports these shapes under public aliases and adds curated request envelopes for endpoints whose query/body shapes are not modelled as named schemas in the spec.

After editing the spec, regenerate with either:

# install the codegen extra once
pip install -e ".[codegen]"

datamodel-codegen \
  --input ../../openapi.yaml --input-file-type openapi \
  --output geog_ai/_openapi_gen.py \
  --output-model-type typing.TypedDict \
  --target-python-version 3.10 \
  --use-schema-description --use-field-description --use-double-quotes

# or from the repo root, regenerates both SDKs in one shot
bash QHPA/marketing/geog/docs/sdks/scripts/generate-types.sh

geog_ai/_openapi_gen.py carries a generated by datamodel-codegen header. Treat it as build output: never hand-edit it; change the spec and rerun the script.

License

Proprietary — © geog.ai. Contact hello@geog.ai.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

geog_ai-0.1.0.tar.gz (21.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

geog_ai-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file geog_ai-0.1.0.tar.gz.

File metadata

  • Download URL: geog_ai-0.1.0.tar.gz
  • Upload date:
  • Size: 21.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for geog_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8e03f919710e3a4e40735c2c554145e36ef0f8f3a2f4975dd7173595dc502ffc
MD5 286e0ac7c8d15623d39dfaca5a3333dc
BLAKE2b-256 a0008bc770d12fbdb61c1930ec3ceba52a1ea4925f570dcd71f9327828546aad

See more details on using hashes here.

File details

Details for the file geog_ai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: geog_ai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for geog_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 efcc63e8b4403afa69ea68015f0f71d5dab412a9b61d3487d79907b5f27edbc7
MD5 4a7cd1eaa8f48a9d6d54829fd72ec733
BLAKE2b-256 e5e85976c52659f07dcf2f7dc053d4a651964959e1fd10a3dcdd38d131e8a995

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page