Python client libraries for Honua, the cloud-native geospatial platform built around honua-server. One typed client covers feature queries, geocoding, map/image export, editing, and server administration across the server's protocol adapters — GeoServices REST (FeatureServer/MapServer/ImageServer/GeocodeServer/GeometryServer), OGC API Features, STAC, OData, WFS/WMS/WMTS, and gRPC streaming — with one-call GeoDataFrame interop for the pandas/GeoPandas stack.
Two independently installable, Apache-2.0 packages live under packages/:
| Package | Import | Description |
|---|---|---|
packages/honua-sdk |
honua_sdk |
Data-plane client — feature queries, geocoding, protocol clients, gRPC streaming, GeoPandas/raster interop, honua CLI |
packages/honua-admin |
honua_admin |
Control-plane client — services, connections, layers, styles, metadata, manifests, compatibility checks (depends on honua-sdk) |
Also in this repo: packages/honua-gp, a proprietary
geoprocessing compatibility layer for teams migrating scripts from ArcGIS
arcpy (separate license, not published). Import it as honua_gp.
Alpha (0.x). APIs may change before 1.0; breaking changes to the public API
are gated by a compatibility snapshot and a
per-capability SDK coverage snapshot.
Releases are automated with release-please and PyPI Trusted Publishing and
ship to PyPI as honua-sdk and honua-admin. After release-please creates a
package tag and GitHub Release, the publication workflow reconciles that exact
release commit, publishes the SDK before the dependent admin package, and
attaches the wheel and source distribution to the GitHub Release.
Requires Python 3.11+ (CI tests 3.11, 3.12, 3.13). From PyPI:
pip install honua-sdk # data-plane client
pip install "honua-sdk[grpc,geopandas,raster]" # + optional extras
pip install honua-admin # control-plane (admin) clientFrom source (always works, and the path for development):
git clone https://github.com/honua-io/honua-sdk-python.git
cd honua-sdk-python
# Data-plane client
pip install ./packages/honua-sdk
# With optional extras: gRPC streaming, GeoPandas vector interop,
# raster interop (rasterio / rioxarray / xarray)
pip install "./packages/honua-sdk[grpc,geopandas,raster]"
# Control-plane (admin) client — installs honua-sdk alongside it
pip install ./packages/honua-sdk ./packages/honua-adminFor the published SDK with GeoPandas support, use the PyPI extra:
pip install "honua-sdk[geopandas]"This uses the configured package index and version constraints, just like the core install above. For a reproducible release, pin the same SDK version for both the core package and its extras; installing an older Git tag would replace the installed SDK with that older version.
The repo-root pyproject.toml is intentionally not installable (it holds
shared tool config only) — install the per-package directories, not ..
INSTALL.md has extras details and install-time troubleshooting.
| Goal | Start here |
|---|---|
| Query features in 5 minutes | docs/quickstart.md |
| Stream features over gRPC | INSTALL.md#with-grpc |
| Build an ETL pipeline | examples/geospatial_etl/ |
| Wire a FastAPI service | examples/fastapi_spatial_service.py |
| Run spatial queries from Jupyter / pandas | docs/quickstart.md + examples/data_quality_report.py |
| Manage services & connections | packages/honua-admin/ |
| Understand the protocol matrix | docs/protocol-parity.md |
| Diagnose an error | docs/quickstart.md#common-errors |
Query features through the canonical Source / Query / Result API and
convert to a GeoDataFrame in one call. The examples below read the public,
anonymous demo server at https://demo.honua.io and its maui-zoning
FeatureServer (layer 2: zoning polygons with zone_code, zone_dist,
cp_area and island). To use your own server, change the base URL, service
and layer.
from honua_sdk import HonuaClient, Query, SourceDescriptor, SourceLocator
with HonuaClient("https://demo.honua.io") as client:
source = client.source(
SourceDescriptor(
id="maui-zoning",
protocol="geoservices-feature-service",
locator=SourceLocator(service_id="maui-zoning", layer_id=2),
)
)
result = source.query(Query(where="island = 'Maui'", out_fields=["*"]))
print(f"Found {len(result.features)} features")
for feature in result.features[:3]:
print(feature.id, feature.properties)
# Requires the [geopandas] extra
gdf = result.to_geodataframe() # GeoDataFrame with geometry column + CRS set
print(gdf.head(), gdf.crs)client.source(...) returns a source-bound facade with query(),
query_all(), stream()/iter_features(), apply_edits(), and
protocol(...). source.query() returns a canonical Result of normalized
QueryFeature entries (id, properties, geometry, protocol, source,
raw) — the same shape across FeatureServer, OGC API Features, STAC, and
OData. The reverse helper honua_sdk.geopandas.geodataframe_to_features turns
an edited GeoDataFrame back into apply_edits payloads.
The server advertises each layer's OGC API Features collection id in
collections(); the id comes from the layer's publication, so it is not
always the layer id. On the demo publication the maui-zoning layer above is
collection "2"; on your own server, pick the id from collections():
from honua_sdk import HonuaClient
with HonuaClient("https://demo.honua.io") as client:
ogc = client.ogc_features()
collections = ogc.collections()
zoning = ogc.collection("2")
items = zoning.items(limit=100, filter="island = 'Maui'")
feature = zoning.item(items["features"][0]["id"])from honua_sdk import HonuaGeocodingClient
with HonuaGeocodingClient("https://demo.honua.io") as geocoder:
results = geocoder.forward_geocode("1600 Pennsylvania Ave NW, Washington, DC")
for r in results:
print(f"{r.address} ({r.latitude}, {r.longitude}) score={r.score}")Every HTTP workflow has an async counterpart with the same factory and method names — works with FastAPI, asyncio pipelines, and Jupyter:
import asyncio
from honua_sdk import AsyncHonuaClient, Query, SourceDescriptor, SourceLocator
async def main() -> None:
async with AsyncHonuaClient("https://demo.honua.io") as client:
source = client.source(
SourceDescriptor(
id="maui-zoning",
protocol="geoservices-feature-service",
locator=SourceLocator(service_id="maui-zoning", layer_id=2),
)
)
result = await source.query(Query(where="1=1"))
print(f"Found {len(result.features)} features")
asyncio.run(main())asyncio.run(main()) is for scripts. Jupyter and IPython already run an event
loop, where asyncio.run raises RuntimeError; call await main() in a
notebook cell instead.
Admin needs a server of your own: the public demo returns 401 for
/api/v1/admin/*. Install honua-admin, then set HONUA_API_KEY to an admin
API key for your server (the
honua-server quickstart
shows how to mint one with HONUA_ADMIN_PASSWORD).
import os
from honua_admin import HonuaAdminClient
# Admin needs a server of your own: the public demo returns 401 for /api/v1/admin/*.
# Mint a key with HONUA_ADMIN_PASSWORD on your server - see the honua-server quickstart.
with HonuaAdminClient("https://your-honua-server.com", api_key=os.environ["HONUA_API_KEY"]) as admin:
compatibility = admin.check_compatibility()
if not compatibility.supported:
raise RuntimeError("; ".join(compatibility.reasons))
features = admin.get_capability_flags()
if features.manifest_apply:
manifest = admin.get_manifest()
print(f"Manifest resources: {len(manifest.resources)}")Protocol IDs. Docs and examples use the canonical cross-SDK protocol ids (
geoservices-feature-service,ogc-features,stac,odata, ...). Common aliases (feature-server,ogc-api-features, ...) are accepted at runtime and normalized byhonua_sdk.normalize_protocol(...); the full table lives inhonua_sdk.PROTOCOL_ALIASES. Compact helpers (client.query(...),client.query_features(...)) remain for one-liners — see Protocol Examples for every wrapper and Protocol Parity for the Python/JS coverage map.
| Typed, canonical query surface | Source / Query / Result with normalized QueryFeature across FeatureServer, OGC Features, STAC, OData |
| Protocol clients | GeoServices (Feature/Map/Image/Geocode/Geometry/Scene/Elevation servers), OGC API Features/Maps/Tiles/Coverages/Processes/Records, STAC, OData, WFS, WMS, WMTS, geoprocessing + workflow wrappers — see protocol parity |
| GIS interop | Result.to_geodataframe(), features_to_geodataframe (Esri JSON aware), raster results via rasterio/rioxarray ([raster] extra) |
| gRPC streaming | honua_sdk.grpc.HonuaGrpcClient / HonuaGrpcAsyncClient for unary + streaming feature queries ([grpc] extra) |
| Sync + async | HonuaClient / AsyncHonuaClient in lockstep (sync clients generated from the async source of truth) |
| Automatic retry | 429/502/503/504 with exponential backoff and Retry-After support for idempotent methods (POST only when opted in via retry_methods on the retry transport); configurable via max_retries |
| Typed errors | HonuaAuthError, HonuaRateLimitError, HonuaHttpError, HonuaTimeoutError, HonuaTransportError — see common errors |
| CLI | honua (services / layers / style apply / sanitized doctor diagnostics) and honua-migrate (offline ArcPy script scan / translate / run, plus .pyt / .atbx toolbox and GP-service classification, with optional server-attested toolbox translation verdicts via --server) |
| Quality gates | mypy strict workspace-wide, 94% coverage gate, public-API compatibility snapshot, per-capability SDK coverage snapshot, live-server conformance lane against shared geospatial-grpc fixtures |
The rendered docs site lives at honua-io.github.io/honua-sdk-python (versioned MkDocs build of docs/). Platform-level docs are at honua.io and honua.gitbook.io/honuaio.
- 5-Minute Quickstart — query, GeoDataFrame, plot, common errors
- Core Client — typed service, FeatureServer, applyEdits, pagination, error handling
- Protocol Examples — OGC, STAC, WFS, WMS, WMTS, OData, geocoding, gRPC with response shapes
- Authentication — refreshable bearer tokens, storage, rotation, failure modes
- Pagination and retries & timeouts
- Sanitized diagnostic bundles — the
honua doctorbundle format - Geospatial ETL demo — script-first ETL flow with notebook companion
- Compatibility — supported server matrix and public-API snapshot gate
- SDK coverage — per-capability coverage snapshot gate
- Troubleshooting — base URL, auth, staging smoke env vars, cleanup
| Repo | What it is |
|---|---|
| honua-server | Flagship multi-protocol geospatial server this SDK talks to |
| honua-sdk-js | JavaScript/TypeScript SDKs + MCP server |
| honua-sdk-dotnet | .NET SDKs |
| honua-console | Display-and-approve web console; Studio is Preview and is not part of the qualified 2026.1 scope |
| honua-qgis-plugin | QGIS plugin (private preview; repo not yet public) |
| geospatial-grpc | Vendor-neutral gRPC protocol standard; source of this repo's conformance fixtures |
Run these from a clone of this repository (see Install). Besides
Python 3.11+, the test suite needs Node.js with node on PATH: the honua
CLI forwards honua admin ... to the JavaScript CLI, and tests/test_cli.py
checks that forwarding.
# Editable install of both packages with extras
pip install -e "packages/honua-sdk[grpc,geopandas]"
pip install -e "packages/honua-admin"
pip install pytest pytest-cov ruff mypy
# Lint + type-check (mypy runs in strict mode)
ruff check .
python -m mypy packages/honua-sdk/honua_sdk packages/honua-admin/honua_admin
# Deterministic local test suite
python3 -m pytest tests/ -q
# Public-API compatibility gate
python3 scripts/compatibility_gate.pySync clients (client.py, _client.py) are generated from their async
counterparts — edit the async module and run python scripts/gen_sync.py;
never hand-edit the generated files.
Opt-in integration lanes (staging smoke, live-server conformance, release
smoke) need HONUA_BASE_URL and the --run-integration flag; see
docs/troubleshooting.md and
docs/compatibility.md for env vars, markers, and
result artifacts.
Bugs and feature requests: GitHub issues. Pull requests are welcome — CI enforces lint, strict typing, the coverage gate, and the compatibility snapshot.
Report vulnerabilities to security@honua.io — see the org security policy. Do not open public issues for security reports.
honua-sdk and honua-admin are licensed under
Apache-2.0. packages/honua-gp is proprietary (see its LICENSE)
and is not published.