honua-sdk › Source facade¶
The canonical entry point for portable code is the Source facade —
client.source(SourceDescriptor(...)).query(Query(...)) returns a
Result[QueryFeature] regardless of whether the
underlying source is a GeoServices FeatureServer, an OGC Features collection,
a STAC catalog, or an OData entity set. Prefer this path when you want
behaviour that is consistent across protocols; reach for the
protocol-specific clients (feature_server(...), ogc_features(),
stac(), odata()) when you need protocol-native operations not
covered by the canonical surface.
See Protocol examples for side-by-side recipes that show the same query running against each supported protocol via the facade.
from honua_sdk import Query, SourceDescriptor, SourceLocator
descriptor = SourceDescriptor(id="svc", protocol="geoservices-feature-service",
locator=SourceLocator(service_id="svc", layer_id=0))
result = client.source(descriptor).query(Query(where="1=1"))
arcpy.da-style cursors¶
For geoprocessing authoring the facade exposes the arcpy.da cursor idioms over
the streaming query and batched apply_edits:
source = client.source(descriptor)
# SearchCursor: lazily iterate (attrs, geometry) rows; "SHAPE@" selects geometry.
for name, shape in source.search_cursor(["NAME", "SHAPE@"], where="POP > 1000"):
...
# UpdateCursor: iterate rows, edit, write back in batches.
with source.update_cursor(where="STATUS = 'stale'") as cursor:
for row in cursor:
cursor.update_row(row, attributes={"STATUS": "reviewed"})
# InsertCursor: batched feature inserts.
with source.insert_cursor() as cursor:
cursor.insert_row({"NAME": "New"}, {"x": -100.0, "y": 40.0})
Source.schema() returns a typed LayerSchema
(arcpy.Describe analogue) and Source.to_geodataframe(...) returns a GeoPandas
GeoDataFrame in one call (the Spatially-Enabled-DataFrame equivalent; requires
the geopandas extra).
See also: Models for the Query / Result shapes, and
Core client model for how the facade composes over the
underlying clients.
honua_sdk.source.Source
¶
Source-bound facade over the shared query API and protocol escape hatches.
Binds a :class:SourceDescriptor to a :class:HonuaClient so callers
can issue protocol-neutral :class:Query requests (query,
stream) without rebuilding the source identifier on each call.
Routes requests through the canonical query dispatcher and exposes
capability introspection via :meth:supports; falls back to the
underlying protocol clients (feature_server, ogc_features,
stac, odata) when callers need protocol-specific escape
hatches. Construct via :meth:HonuaClient.source rather than
directly.
Attributes:
| Name | Type | Description |
|---|---|---|
descriptor |
The normalized :class: |
query(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None, timeout=None, extra_headers=None, idempotency_key=None)
¶
Run a canonical source query and collect normalized features.
Accepts either a :class:Query (or mapping) plus explicit keyword
overrides matching :class:Query fields. Two legacy keyword aliases
remain accepted for source compatibility but emit
:class:DeprecationWarning; migrate to the canonical
:class:Query field names:
fields=is deprecated — useout_fields=.filter=is deprecated — usewhere=(see :class:Queryfor filter-routing semantics across SQL- and CQL-style protocols).
Pass cql_filter= explicitly when targeting OGC Features / STAC
with a CQL2-text expression — that bypasses the where field
and routes the expression directly to the protocol's filter
field. Passing only where= against an OGC/STAC source raises
:class:ValueError; opt into the old silent forwarding behavior
with where_as_cql=True if you have verified the string is
already valid CQL2-text.
Per-call timeout / extra_headers / idempotency_key are
forwarded to the bound client's query method (and from there
to FeatureServer, OGC Features, and STAC pagination wrappers).
query_all(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None)
¶
Return all normalized features for a canonical source query.
stream(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None, timeout=None, extra_headers=None, idempotency_key=None)
¶
Stream normalized features for a canonical source query.
Per-call timeout / extra_headers / idempotency_key are
forwarded to the bound client's iter_query method.
iter_features(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None)
¶
Alias for stream() using a Python iterator name.
apply_edits(*, adds=None, updates=None, deletes=None, rollback_on_failure=True, idempotency_key=None, timeout=None, extra_headers=None)
¶
Apply edits for source protocols that expose a normalized edit helper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adds
|
Sequence[Mapping[str, Any]] | None
|
Sequence of feature mappings to insert. |
None
|
updates
|
Sequence[Mapping[str, Any]] | None
|
Sequence of feature mappings to update by |
None
|
deletes
|
Sequence[int] | str | None
|
Either a sequence of object ids or a comma-string of ids to delete. |
None
|
rollback_on_failure
|
bool
|
Whether the server should roll the entire batch back if any individual edit fails. |
True
|
idempotency_key
|
str | None
|
Stripe-style |
None
|
timeout
|
float | Timeout | None
|
Per-request timeout forwarded to the transport layer. |
None
|
extra_headers
|
Mapping[str, str] | None
|
Additional HTTP headers merged onto the request. |
None
|
protocol(kind=None)
¶
Return the native protocol client for source-specific operations.
schema(layer_id=None)
¶
Return a typed :class:LayerSchema for this source's layer.
The arcpy.Describe / ListFields analogue: fetches the
FeatureServer layer metadata and parses it into typed fields, geometry
type, spatial-reference WKID, and extent. layer_id defaults to the
source descriptor's layer.
search_cursor(fields=None, *, where=None, geometry_filter=None, **query_kwargs)
¶
Open a lazy :class:~honua_sdk.cursors.SearchCursor over this source.
The arcpy.da.SearchCursor analogue — iterate (geometry, attrs)
rows lazily without materializing the whole result.
iter_rows(fields=None, *, where=None, geometry_filter=None, **query_kwargs)
¶
Lazily iterate cursor rows (alias for search_cursor(...) iteration).
update_cursor(fields=None, *, where=None, geometry_filter=None, batch_size=200, rollback_on_failure=True, **query_kwargs)
¶
Open an :class:~honua_sdk.cursors.UpdateCursor (iterate + batched write-back).
insert_cursor(*, batch_size=200, rollback_on_failure=True)
¶
Open an :class:~honua_sdk.cursors.InsertCursor (batched feature inserts).
to_geodataframe(query=None, **query_kwargs)
¶
Run a query and return its features as a GeoPandas GeoDataFrame.
First-class SEDF-equivalent: one call from source to geopandas. Requires
the optional geopandas extra.
honua_sdk.source.AsyncSource
¶
Async source-bound facade over the shared query API and protocol escape hatches.
Asynchronous counterpart to :class:Source. Binds a
:class:SourceDescriptor to an :class:AsyncHonuaClient so callers
can await protocol-neutral :class:Query requests (query,
stream) without rebuilding the source identifier on each call.
Capability introspection (:meth:supports) and protocol escape
hatches mirror the sync facade. Construct via
:meth:AsyncHonuaClient.source rather than directly.
Attributes:
| Name | Type | Description |
|---|---|---|
descriptor |
The normalized :class: |
query(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None, timeout=None, extra_headers=None, idempotency_key=None)
async
¶
Run a canonical source query and collect normalized features.
Accepts either a :class:Query (or mapping) plus explicit keyword
overrides matching :class:Query fields. Two legacy keyword aliases
remain accepted for source compatibility but emit
:class:DeprecationWarning; migrate to the canonical
:class:Query field names:
fields=is deprecated — useout_fields=.filter=is deprecated — usewhere=(see :class:Queryfor filter-routing semantics across SQL- and CQL-style protocols).
Pass cql_filter= explicitly when targeting OGC Features / STAC
with a CQL2-text expression — that bypasses the where field
and routes the expression directly to the protocol's filter
field. Passing only where= against an OGC/STAC source raises
:class:ValueError; opt into the old silent forwarding behavior
with where_as_cql=True if you have verified the string is
already valid CQL2-text.
Per-call timeout / extra_headers / idempotency_key are
forwarded to the bound client's query method.
query_all(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None)
async
¶
Return all normalized features for a canonical source query.
stream(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None, timeout=None, extra_headers=None, idempotency_key=None)
async
¶
Stream normalized features for a canonical source query.
Per-call timeout / extra_headers / idempotency_key are
forwarded to the bound client's iter_query method.
iter_features(query=None, *, where=None, out_fields=None, return_geometry=None, bbox=None, spatial_filter=None, limit=None, page_size=None, max_pages=None, cql_filter=None, where_as_cql=None, extra_params=None, fields=None, filter=None)
async
¶
Alias for stream() using a Python iterator name.
apply_edits(*, adds=None, updates=None, deletes=None, rollback_on_failure=True, idempotency_key=None, timeout=None, extra_headers=None)
async
¶
Apply edits for source protocols that expose a normalized edit helper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adds
|
Sequence[Mapping[str, Any]] | None
|
Sequence of feature mappings to insert. |
None
|
updates
|
Sequence[Mapping[str, Any]] | None
|
Sequence of feature mappings to update by |
None
|
deletes
|
Sequence[int] | str | None
|
Either a sequence of object ids or a comma-string of ids to delete. |
None
|
rollback_on_failure
|
bool
|
Whether the server should roll the entire batch back if any individual edit fails. |
True
|
idempotency_key
|
str | None
|
Stripe-style |
None
|
timeout
|
float | Timeout | None
|
Per-request timeout forwarded to the transport layer. |
None
|
extra_headers
|
Mapping[str, str] | None
|
Additional HTTP headers merged onto the request. |
None
|
protocol(kind=None)
¶
Return the native protocol client for source-specific operations.
schema(layer_id=None)
async
¶
Return a typed :class:LayerSchema for this source's layer.
Asynchronous counterpart to :meth:Source.schema. The
arcpy.Describe / ListFields analogue: fetches the FeatureServer
layer metadata and parses it into typed fields, geometry type,
spatial-reference WKID, and extent.
search_cursor(fields=None, *, where=None, geometry_filter=None, **query_kwargs)
¶
Open a lazy :class:~honua_sdk.cursors.AsyncSearchCursor over this source.
iter_rows(fields=None, *, where=None, geometry_filter=None, **query_kwargs)
¶
Lazily iterate cursor rows (alias for search_cursor(...) iteration).
update_cursor(fields=None, *, where=None, geometry_filter=None, batch_size=200, rollback_on_failure=True, **query_kwargs)
¶
Open an :class:~honua_sdk.cursors.AsyncUpdateCursor (iterate + batched write-back).
insert_cursor(*, batch_size=200, rollback_on_failure=True)
¶
Open an :class:~honua_sdk.cursors.AsyncInsertCursor (batched feature inserts).
to_geodataframe(query=None, **query_kwargs)
async
¶
Run a query and return its features as a GeoPandas GeoDataFrame.
First-class SEDF-equivalent: one await from source to geopandas.
Requires the optional geopandas extra.
honua_sdk.cursors.SearchCursor
¶
Lazy row iterator over a source query (arcpy.da.SearchCursor analogue).
Wraps :meth:Source.stream, yielding :class:Row objects one at a time so
a tool never materializes the whole result. Pass fields to iterate
positional value tuples (with "SHAPE@" selecting geometry) instead of
rows. Supports the context-manager and iterator protocols.
rows()
¶
Iterate :class:Row objects regardless of the fields selection.
honua_sdk.cursors.UpdateCursor
¶
Bases: _BaseWriteCursor
Iterate rows and write edits back (arcpy.da.UpdateCursor analogue).
Iterating yields :class:Row objects (lazily, via a search cursor). Call
:meth:update_row with new attributes/geometry to queue an update keyed by
the row's object id; queued updates flush in batches through
Source.apply_edits(updates=...) on :meth:flush / context-manager exit.
honua_sdk.cursors.InsertCursor
¶
Bases: _BaseWriteCursor
Batched feature inserts (arcpy.da.InsertCursor analogue).
Accumulate rows with :meth:insert_row; they are flushed to the source via
Source.apply_edits(adds=...) once batch_size is reached, on
:meth:flush, or when the context manager exits.
honua_sdk.cursors.Row
dataclass
¶
A single cursor row: a feature's geometry plus its attribute mapping.
Mirrors an arcpy.da cursor row. :meth:values projects the row onto a
requested field tuple (with the "SHAPE@" token selecting geometry),
giving the positional-tuple ergonomic GP tools expect.
attributes
property
¶
The feature's attribute mapping (GeoJSON properties).
geometry
property
¶
The row geometry as a Shapely geometry (None when absent).
values(fields)
¶
Project the row onto fields as a positional tuple.
The "SHAPE@" token yields the Shapely geometry; every other name is
looked up in the attribute mapping (None when missing).