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
pydanticor 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 eventualJobResponse[TResult]fromGET /jobs/{id}only populates"result"whenjob.status == "complete"; on"failed"inspectjob["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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e03f919710e3a4e40735c2c554145e36ef0f8f3a2f4975dd7173595dc502ffc
|
|
| MD5 |
286e0ac7c8d15623d39dfaca5a3333dc
|
|
| BLAKE2b-256 |
a0008bc770d12fbdb61c1930ec3ceba52a1ea4925f570dcd71f9327828546aad
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efcc63e8b4403afa69ea68015f0f71d5dab412a9b61d3487d79907b5f27edbc7
|
|
| MD5 |
4a7cd1eaa8f48a9d6d54829fd72ec733
|
|
| BLAKE2b-256 |
e5e85976c52659f07dcf2f7dc053d4a651964959e1fd10a3dcdd38d131e8a995
|