These examples cover the public protocol wrappers exposed by honua_sdk.
HTTP protocol wrappers return protocol-native payloads:
| Surface | Wrapper | Return shape |
|---|---|---|
| OGC API Features | client.ogc_features() |
JSON dict GeoJSON documents, paged iterators, or list[dict] from items_all() |
| OGC API Maps | client.ogc_maps() |
JSON dict metadata and bytes map images |
| OGC API Tiles | client.ogc_tiles() |
JSON dict metadata and bytes tiles |
| OGC API Coverages | client.ogc_coverages() |
JSON dict metadata and bytes coverage payloads |
| OGC API Processes | client.ogc_processes() |
JSON dict; dismiss_job() returns None |
| STAC | client.stac() |
JSON dict STAC Catalog, Collection, Item, search payloads, and paged iterators |
| WFS | client.wfs() |
XML str |
| WMS | client.wms(service_id) |
XML str capabilities, bytes payloads, or BinaryResponse metadata |
| WMTS | client.wmts(service_id) |
XML str capabilities, bytes tiles, or BinaryResponse metadata |
| OData | client.odata() |
JSON dict resources, XML str metadata, query helpers, and paged iterators |
| Geocoding | client.geocoder(), HonuaGeocodingClient |
SDK dataclass models |
| gRPC | HonuaGrpcClient |
SDK dataclass models |
HTTP protocol wrappers, geocoding, and gRPC also have async clients. Async HTTP wrappers use the same factory and method names; await methods that issue requests.
For application code that wants one feature-query shape across data protocols,
use HonuaClient.query() or HonuaClient.iter_query() first. Those helpers
normalize FeatureServer, OGC API Features, STAC, and OData results into
QueryFeature entries. The protocol wrappers below remain the escape hatch for
native payloads, exact protocol options, maps, tiles, XML metadata, and response
headers.
The snippets use these placeholders:
SERVER = "https://your-honua-server.com"
GRPC_TARGET = "your-honua-server.com:50051"
COLLECTION_ID = "parcels"
STAC_COLLECTION_ID = "imagery"
SERVICE_ID = "basemap"
LAYER_ID = 0
BBOX = [-180, -90, 180, 90]ogc_features() returns GeoJSON-style JSON dictionaries. items_pages()
streams FeatureCollection pages, iter_items() streams individual feature
dictionaries, and items_all() collects features into a list.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
ogc = client.ogc_features()
landing = ogc.landing() # dict JSON
collections = ogc.collections() # dict JSON
queryables = ogc.queryables(COLLECTION_ID) # dict JSON
parcels = ogc.collection(COLLECTION_ID)
items = parcels.items(limit=100, bbox=BBOX) # dict GeoJSON FeatureCollection
first_pages = list(parcels.items_pages(page_size=500, max_pages=2))
for feature in parcels.iter_items(page_size=500, limit=1000):
print(feature["id"])
all_items = parcels.items_all(page_size=500, limit=1000) # list[dict]
feature = parcels.item("123") # dict GeoJSON FeatureWith geopandas installed, OGC FeatureCollection JSON can be converted to a
GeoDataFrame through the SDK helper:
from honua_sdk.geopandas import ogc_features_to_geodataframe
gdf = ogc_features_to_geodataframe(items)Async OGC API Features uses AsyncHonuaClient:
from honua_sdk import AsyncHonuaClient
async with AsyncHonuaClient(SERVER) as client:
parcels = client.ogc_features().collection(COLLECTION_ID)
items = await parcels.items(limit=100) # dict GeoJSON FeatureCollection
async for feature in parcels.iter_items(page_size=500, limit=1000):
print(feature["id"])
all_items = await parcels.items_all(page_size=500, limit=1000)Map metadata is JSON. Rendered maps are returned as raw image bytes.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
maps = client.ogc_maps()
landing = maps.landing() # dict JSON
openapi = maps.openapi() # dict JSON
map_png = maps.collection_map(COLLECTION_ID, bbox=BBOX)
styled_png = maps.styled_collection_map(COLLECTION_ID, "default", bbox=BBOX)
tilesets = maps.collection_tilesets(COLLECTION_ID)
print(len(map_png), len(styled_png)) # bytesTileset discovery returns JSON. Tile requests return bytes.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
tiles = client.ogc_tiles()
collections = tiles.collections() # dict JSON
matrix_sets = tiles.tile_matrix_sets() # dict JSON
collection_tilesets = tiles.collection_tilesets(COLLECTION_ID)
tile_png = tiles.tile(
"WebMercatorQuad",
"0",
0,
0,
collection_id=COLLECTION_ID,
)
print(len(tile_png)) # bytesCoverage discovery returns JSON. The coverage payload is returned as bytes, even
when response_format="json" is requested, because deployments may return JSON,
TIFF, or another advertised coverage encoding.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
coverages = client.ogc_coverages()
collections = coverages.collections() # dict JSON
metadata = coverages.collection("elevation") # dict JSON
coverage_json_bytes = coverages.coverage("elevation")
coverage_tiff = coverages.coverage("elevation", response_format="tiff")
print(len(coverage_json_bytes), len(coverage_tiff)) # bytesProcess discovery, execution, job status, and job results return JSON
dictionaries. dismiss_job() sends the delete request and returns None.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
processes = client.ogc_processes()
available = processes.processes() # dict JSON
description = processes.process("buffer") # dict JSON
execution = processes.execute("buffer", {"inputs": {"distance": 10}})
jobs = processes.jobs() # dict JSON
job = processes.job("job-id") # dict JSON
results = processes.job_results("job-id") # dict JSON
processes.dismiss_job("job-id") # NoneThere is one canonical geoprocessing engine: the server (OGC API
Processes). The SDK does not reimplement any analysis (no client-side
buffer/overlay/interpolation/raster math); it is an OGC Processes client plus
last-mile interop that drops server output straight into the tools you
already use. Reach for native libraries (geopandas, shapely, rasterio,
pysal, scikit-learn) for ad-hoc local work, and for server geoprocessing
when you need canonical, repeatable analysis.
The richer client.geoprocessing() client (submit / poll-to-terminal /
fetch-results, plus multi-step plans) exposes interop helpers behind optional
extras:
from honua_sdk import HonuaClient
from honua_sdk.geoprocessing import LayerReference
with HonuaClient(SERVER) as client:
gp = client.geoprocessing()
# Vector: GeoDataFrame in -> server process -> GeoDataFrame out.
# (requires: pip install honua-sdk[geopandas])
out_gdf = gp.execute_dataframe("geometry.buffer", gdf, parameters={"distance": 100})
# Raster: server raster output -> xarray / rasterio.
# (requires: pip install honua-sdk[raster])
layer = LayerReference.from_query_result("layer-123")
data_array = gp.execute_raster("analytics.kernel-density", layer) # xarray.DataArray
# Or convert an already-fetched results document:
results = gp.results("job-id")
data_array = gp.result_to_xarray(results) # xarray.DataArray (via rioxarray)
with gp.result_to_rasterio(results) as dataset: # rasterio dataset
band = dataset.read(1)Heavy geo dependencies stay optional: the base SDK only needs httpx, the
helpers import geopandas / rasterio / rioxarray / xarray lazily, and a
clear ImportError (pointing at the right extra) is raised when they are
absent. The AsyncHonuaClient exposes the same helpers as awaitables.
STAC helpers return STAC JSON dictionaries. Item collection and search responses are GeoJSON-like STAC ItemCollection payloads.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
stac = client.stac()
catalog = stac.catalog() # dict STAC Catalog
collections = stac.collections() # dict JSON
collection = stac.collection(STAC_COLLECTION_ID)
items = stac.items(STAC_COLLECTION_ID, extra_params={"limit": 10})
item_pages = list(stac.item_pages(STAC_COLLECTION_ID, page_size=100, max_pages=2))
item_list = stac.items_all(STAC_COLLECTION_ID, page_size=100, limit=500)
item = stac.item(STAC_COLLECTION_ID, "scene-001")
search = stac.search(json_body={"collections": [STAC_COLLECTION_ID], "limit": 10})
search_items = stac.search_items(
json_body={"collections": [STAC_COLLECTION_ID]},
page_size=100,
limit=500,
)With geopandas installed, STAC ItemCollection/search JSON can be converted to
a GeoDataFrame:
from honua_sdk.geopandas import stac_items_to_geodataframe
gdf = stac_items_to_geodataframe(search)WFS helpers return XML text.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
wfs = client.wfs()
capabilities_xml = wfs.capabilities() # str XML
schema_xml = wfs.describe_feature_type(COLLECTION_ID)
feature_xml = wfs.get_feature(
type_names=COLLECTION_ID,
extra_params={"count": 10},
)
transaction_body = (
'<wfs:Transaction service="WFS" version="2.0.0" '
'xmlns:wfs="http://www.opengis.net/wfs/2.0">...</wfs:Transaction>'
)
transaction_xml = wfs.transaction(transaction_body) # str XMLWMS capabilities are decoded to XML text. Existing map and feature-info helpers
return bytes. Use the *_response() variants when you also need HTTP metadata
such as Content-Type, ETag, or cache headers.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
wms = client.wms(SERVICE_ID)
capabilities_xml = wms.capabilities() # str XML
map_png = wms.map(
layers=COLLECTION_ID,
bbox=BBOX,
width=512,
height=512,
crs="EPSG:4326",
)
map_response = wms.map_response(
layers=COLLECTION_ID,
bbox=BBOX,
width=512,
height=512,
)
info = wms.feature_info(
layers=COLLECTION_ID,
query_layers=COLLECTION_ID,
i=256,
j=256,
bbox=BBOX,
width=512,
height=512,
)
print(len(map_png), len(info)) # bytes
print(map_response.content_type, map_response.etag)WMTS capabilities are XML text. Existing tile helpers return bytes. Use
tile_response() when tile payload metadata is needed.
from honua_sdk import HonuaClient
with HonuaClient(SERVER) as client:
wmts = client.wmts(SERVICE_ID)
capabilities_xml = wmts.capabilities() # str XML
tile_png = wmts.tile(
layer=COLLECTION_ID,
tile_matrix_set="WebMercatorQuad",
tile_matrix="0",
tile_row=0,
tile_col=0,
)
tile_response = wmts.tile_response(
layer=COLLECTION_ID,
tile_matrix_set="WebMercatorQuad",
tile_matrix="0",
tile_row=0,
tile_col=0,
)
print(len(tile_png)) # bytes
print(tile_response.content_type, tile_response.cache_control)OData service, layer, and feature resources return JSON dictionaries. The
$metadata endpoint returns XML text. Common OData parameters can be passed as
direct keyword arguments or grouped in ODataQuery.
from honua_sdk import HonuaClient
from honua_sdk.protocols import ODataQuery
with HonuaClient(SERVER) as client:
odata = client.odata()
service_document = odata.service_document() # dict JSON
metadata_xml = odata.metadata() # str XML
layers = odata.layers(
query=ODataQuery(select=["Id", "Name"], orderby=["Name"], count=True),
top=50,
)
for layer in odata.iter_layers(page_size=100, limit=500):
print(layer["Id"])
layer = odata.layer(LAYER_ID) # dict JSON
features = odata.features(
layer_id=LAYER_ID,
filter="Status eq 'active'",
select=["ObjectId", "Name"],
)
feature_pages = list(odata.features_pages(layer_id=LAYER_ID, page_size=500, max_pages=2))
feature_list = odata.features_all(layer_id=LAYER_ID, page_size=500, limit=2000)
feature = odata.feature(LAYER_ID, 123) # dict JSONAsyncHonuaClient exposes the same HTTP protocol factories as HonuaClient.
Factory methods are synchronous; methods that issue requests are awaited:
from honua_sdk import AsyncHonuaClient
async with AsyncHonuaClient(SERVER) as client:
items = await client.ogc_features().collection(COLLECTION_ID).items(limit=100)
map_png = await client.ogc_maps().collection_map(COLLECTION_ID, bbox=BBOX)
tile_png = await client.ogc_tiles().tile("WebMercatorQuad", "0", 0, 0, collection_id=COLLECTION_ID)
coverage = await client.ogc_coverages().coverage("elevation", response_format="tiff")
processes = await client.ogc_processes().processes()
stac_items = await client.stac().items(STAC_COLLECTION_ID, extra_params={"limit": 10})
stac_item_list = await client.stac().items_all(STAC_COLLECTION_ID, page_size=100, limit=500)
wfs_xml = await client.wfs().get_feature(type_names=COLLECTION_ID)
wms_png = await client.wms(SERVICE_ID).map(layers=COLLECTION_ID, bbox=BBOX, width=512, height=512)
wms_response = await client.wms(SERVICE_ID).map_response(
layers=COLLECTION_ID,
bbox=BBOX,
width=512,
height=512,
)
wmts_tile = await client.wmts(SERVICE_ID).tile(
layer=COLLECTION_ID,
tile_matrix_set="WebMercatorQuad",
tile_matrix="0",
tile_row=0,
tile_col=0,
)
odata_features = await client.odata().features_all(layer_id=LAYER_ID, page_size=500, limit=2000)Geocoding returns SDK dataclasses rather than raw dictionaries.
from honua_sdk import HonuaClient, HonuaGeocodingClient
with HonuaClient(SERVER) as client:
geocoder = client.geocoder()
suggestions = geocoder.suggest("1600 Pennsylvania")
with HonuaGeocodingClient(SERVER) as geocoder:
matches = geocoder.forward_geocode("1600 Pennsylvania Ave NW, Washington, DC")
suggestions = geocoder.suggest("1600 Pennsylvania")
reverse = geocoder.reverse_geocode(38.8977, -77.0365)
for match in matches:
print(match.address, match.latitude, match.longitude, match.score)
if reverse is not None:
print(reverse.address)Async geocoding uses the same method names and can also be reached from
AsyncHonuaClient.geocoder():
from honua_sdk import AsyncHonuaClient, AsyncHonuaGeocodingClient
async with AsyncHonuaClient(SERVER) as client:
suggestions = await client.geocoder().suggest("1600 Pennsylvania")
async with AsyncHonuaGeocodingClient(SERVER) as geocoder:
matches = await geocoder.forward_geocode("1600 Pennsylvania Ave NW")
reverse = await geocoder.reverse_geocode(38.8977, -77.0365)The gRPC client requires the grpc extra:
pip install honua-sdk[grpc]Unary calls return QueryFeaturesResponse dataclasses. Streaming calls yield
FeaturePage dataclasses.
from honua_sdk.grpc import HonuaGrpcClient, QueryFeaturesRequest, build_grpc_metadata
request = QueryFeaturesRequest(
service_id="test_service",
layer_id=0,
out_fields=["objectid", "name"],
return_geometry=True,
)
metadata = build_grpc_metadata(bearer_token="token")
with HonuaGrpcClient(GRPC_TARGET, insecure=True, metadata=metadata) as grpc_client:
response = grpc_client.query_features(request)
print(response.count, len(response.features)) # QueryFeaturesResponse
for page in grpc_client.query_features_stream(request):
print(page.is_last_page, len(page.features)) # FeaturePageAsync gRPC uses HonuaGrpcAsyncClient:
from honua_sdk.grpc import HonuaGrpcAsyncClient, QueryFeaturesRequest
request = QueryFeaturesRequest(service_id="test_service", layer_id=0)
async with HonuaGrpcAsyncClient(GRPC_TARGET, insecure=True) as grpc_client:
response = await grpc_client.query_features(request)
async for page in grpc_client.query_features_stream(request):
print(len(page.features))The protocol wrappers keep native protocol response shapes. When you query a
GeoServices FeatureServer layer and want an SDK-supported GeoDataFrame
conversion, use honua_sdk.geopandas:
Legacy / compact form -- equivalent to
client.source(...).query(...). TheSourceAPI returns typedResult/QueryFeatureobjects; prefer it in new code.
from honua_sdk import HonuaClient
from honua_sdk.geopandas import features_to_geodataframe
with HonuaClient(SERVER) as client:
response = client.query_features(service_id="test_service", layer_id=LAYER_ID)
gdf = features_to_geodataframe(response) # geopandas.GeoDataFrame