API reference¶
This page documents the public surface exposed at the top of the restgdf
namespace: the FeatureLayer and Directory
entry points, the ArcGISTokenSession wrapper, and the
migration helpers in restgdf.compat.
The pydantic response models (LayerMetadata, FeaturesResponse,
CrawlReport and friends) live on Pydantic models. Internal utility modules
are on Utilities.
The base pip install restgdf surface covers metadata/query helpers,
raw-row iteration, crawl/auth utilities, and all pydantic models. Install
restgdf[geo] for GeoDataFrame and pandas-backed APIs such as
FeatureLayer.get_gdf(), sample_gdf(), head_gdf(), fieldtypes,
get_value_counts(), and get_nested_count().
FeatureLayer¶
- class restgdf.FeatureLayer(url, session, where='1=1', token=None, **kwargs)[source]¶
Bases:
objectA class for interacting with an ArcGIS REST FeatureLayer.
- Variables:
metadata (
restgdf.LayerMetadata) – Pydantic-validated layer metadata (name, fields, max record count, advanced query capabilities, …). Replaces the pre-2.0 rawdict. Extra keys sent by the server are preserved viaextra="allow"and reachable throughmetadata.model_extra.name (
str) – Convenience alias formetadata.name.fields (
tuple[str,]) – Field names consumed by restgdf.object_id_field (
str) – Resolved object-id field name ("OBJECTID"when the server omits it).count (
int) – Feature count, validated viaCountResponseat prep time.
- async prep()[source]¶
Fetch and validate layer metadata from the server.
Populates
metadata,name,fields,object_id_field, andcount. Must be called before accessing any metadata attributes unless the instance was created viafrom_url()(which calls this method automatically).- Raises:
ValueError – If the URL does not point to a Feature Layer (e.g. a Table or Map Service root).
See also
from_urlRecommended constructor that calls
prepautomatically.
- property fieldtypes: pandas.DataFrame¶
Return field metadata as a DataFrame when pandas is available.
- async classmethod from_url(url, **kwargs)[source]¶
Create a prepared FeatureLayer from a URL.
This is the recommended constructor. It instantiates the class and calls
prep()so all metadata attributes are immediately available on the returned instance.- Parameters:
url (
str) – ArcGIS REST FeatureLayer endpoint URL (must end with a numeric layer ID).**kwargs – Forwarded to
__init__()— acceptssession,where,token, and any extra HTTP request arguments.
- Returns:
A fully prepared instance with metadata loaded.
- Return type:
- Raises:
ValueError – If url does not end with a number, conflicting tokens are provided, or the endpoint is not a Feature Layer.
See also
__init__Low-level constructor (requires a manual
prepcall).
- async get_oids()[source]¶
Return all object IDs matching the current WHERE filter.
Delegates to
get_unique_values()using the resolvedobject_id_field.- Returns:
Sorted list of object ID values for the filtered feature set.
- Return type:
list[int]
- async get_gdf()[source]¶
Get a GeoDataFrame from an ArcGIS FeatureLayer.
The returned
GeoDataFramecarriesgdf.attrs["spatial_reference"]populated from the layer’s metadata envelope (R-65) when the layer advertises a spatial reference viaextent.spatialReferenceor top-levelspatialReference.
- async iter_pages(*, order='request', max_concurrent_pages=None, on_truncation='raise', **kwargs)[source]¶
Yield raw ArcGIS query-page envelopes from this FeatureLayer.
- Parameters:
order –
"request"(default) yields pages in submit order."completion"yields pages as the underlying fetches complete (may reorder relative to the pagination plan).max_concurrent_pages – Upper bound on concurrent in-flight page fetches.
None(default) leaves concurrency unbounded.on_truncation – Behavior when a page reports
exceededTransferLimit=true:"raise"(default) — raiserestgdf.errors.RestgdfResponseErrorwithcontext='exceededTransferLimit'."ignore"— log arestgdf.paginationwarning and yield the truncated page anyway."split"— bisect the predicate’s OID list and recurse (max depth 32; irreducible partitions raise).
- Yields:
dict– The full raw response envelope for each page (features,objectIdFieldName,exceededTransferLimit, etc.).
Notes
When telemetry is enabled, emits exactly ONE INTERNAL parent span named
feature_layer.streamwrapping the per-page loop (R-61). No per-page restgdf child spans are emitted.
- async iter_features(*, order='request', max_concurrent_pages=None, on_truncation='raise', **kwargs)[source]¶
Yield one raw ArcGIS feature dict at a time.
Thin wrapper over
iter_pages()that flattens each page’sfeatureslist. Seeiter_pages()for parameter semantics.
- async stream_features(*, order='request', max_concurrent_pages=None, on_truncation='raise', **kwargs)¶
Yield one raw ArcGIS feature dict at a time.
Thin wrapper over
iter_pages()that flattens each page’sfeatureslist. Seeiter_pages()for parameter semantics.
- async stream_feature_batches(*, order='request', max_concurrent_pages=None, on_truncation='raise', **kwargs)[source]¶
Yield one list of raw feature dicts per page.
See
iter_pages()for parameter semantics.
- async stream_rows(*, order='request', max_concurrent_pages=None, on_truncation='raise', **kwargs)[source]¶
Yield row-shaped dicts (attributes plus raw geometry).
Each row is the layer feature’s
attributesmerged with ageometrykey holding the ArcGIS geometry dict verbatim. Seeiter_pages()for parameter semantics.
- async stream_gdf_chunks(**kwargs)[source]¶
Yield
GeoDataFramechunks; each chunk’sattrscarries spatial_reference (R-65).Requires the optional geo stack (
geopandas/pyogrio).
- async get_df(resolve_domains=False)[source]¶
Get a pandas DataFrame from an ArcGIS FeatureLayer.
Tabular row view: attributes plus any raw
geometrydict returned by the server, with no geopandas/pyogrio dependency. Raisesrestgdf.errors.OptionalDependencyErrorwhenpandasis not installed.This is the pandas-only counterpart to
get_gdf()— prefer it when callers only need tabular access and want to avoid the full geo dependency stack.- Parameters:
resolve_domains – When
True, coded-value domain fields are post-processed so the DataFrame contains the human-readablenamerather than the rawcode. Codes absent from the domain’scodedValuestable pass through unchanged. Range domains are not validated or coerced. Defaults toFalse— the historical behavior where the DataFrame faithfully mirrors the server payload. No additional HTTP traffic is issued; resolution uses the already-loadedFeatureLayer.metadatafetched duringprep().
Examples
>>> df = await layer.get_df(resolve_domains=True) >>> df["STATUS"].head().tolist() ['Active', 'Inactive', 'Active', ...]
- async row_dict_generator(**kwargs)[source]¶
Asynchronously yield rows from a GeoDataFrame as dictionaries.
Deprecated since version 2.0: Use
stream_rows()instead. This method emits aDeprecationWarningand continues to delegate to the module-levelrow_dict_generatorhelper for backwards compatibility with existingunittest.mock.patchtargets. Scheduled for removal in a future release.
- async get_unique_values(fields, sortby=None)[source]¶
Get unique values for one or more fields.
Results are cached per
(fields, sortby)key for the lifetime of this instance.- Parameters:
- Returns:
A plain list when fields is a single string, or a DataFrame when fields is a tuple.
- Return type:
listorDataFrame- Raises:
FieldDoesNotExistError – If any requested field is not present in the layer schema.
- async get_value_counts(field)[source]¶
Get value counts for a single field.
Results are cached per field for the lifetime of this instance.
- Parameters:
field (
str) – The field name to compute value counts for.- Returns:
A pandas DataFrame with one row per distinct value and an associated count column.
- Return type:
DataFrame- Raises:
FieldDoesNotExistError – If field is not present in the layer schema.
- async get_nested_count(fields)[source]¶
Get nested (cross-tabulated) value counts for multiple fields.
Results are cached per fields tuple for the lifetime of this instance.
- Parameters:
fields (
tupleofstr) – Two or more field names to cross-tabulate.- Returns:
A pandas DataFrame with one row per unique combination of values across the requested fields and an associated count.
- Return type:
DataFrame- Raises:
FieldDoesNotExistError – If any field in fields is not present in the layer schema.
- async getoids()[source]¶
Deprecated alias for
get_oids().
- async samplegdf(n=10)[source]¶
Deprecated alias for
sample_gdf().
- async headgdf(n=10)[source]¶
Deprecated alias for
head_gdf().
- async getuniquevalues(fields, sortby=None)[source]¶
Deprecated alias for
get_unique_values().
- async getvaluecounts(field)[source]¶
Deprecated alias for
get_value_counts().
- async getnestedcount(fields)[source]¶
Deprecated alias for
get_nested_count().
- async where(wherestr)[source]¶
Create a refined
FeatureLayerbound towherestr.BL-46: when the current instance has already resolved its schema via
prep(), the refined child reuses the parent’s cachedmetadata/name/fields/object_id_fieldso the expensive metadata GET (?f=json) is not re-issued. The feature-count POST is still issued, but scoped to the refinedwhere_clausesorefined.countis correct for the refined filter.
Directory¶
- class restgdf.Directory(url, session, token=None)[source]¶
Bases:
objectA class for interacting with ArcGIS Server directories.
- Variables:
metadata (
Optional[restgdf.LayerMetadata]) – Pydantic-validated root metadata populated byprep().Noneuntilprep(orfrom_url()) has run.services (
Optional[list[restgdf.CrawlServiceEntry]]) – Services discovered by the most recentcrawl()call. Each entry carriesname,url,type, and a parsedmetadata(LayerMetadataorNoneif that service’s metadata call failed).services_with_feature_count (
Optional[list[restgdf.CrawlServiceEntry]]) – Same asservicesbut populated with feature counts whencrawl()was invoked withreturn_feature_count=True.report (
Optional[restgdf.CrawlReport]) – The full crawl report (services + per-stage errors + root metadata) from the most recentcrawl()call. Use this when you need to inspect failures that were silently captured instead of raised.
- async prep()[source]¶
Fetch and validate directory metadata from the server.
Populates
metadatawith aLayerMetadatainstance. Must be called before accessing metadata unless the instance was created viafrom_url().
- async classmethod from_url(url, **kwargs)[source]¶
Create a prepared Directory from a URL.
This is the recommended constructor. It instantiates the class and calls
prep()so metadata is immediately available.
- async crawl(return_feature_count=False)[source]¶
Discover all services under this directory recursively.
Results are cached — subsequent calls with the same return_feature_count value return the cached list without additional HTTP traffic.
- Parameters:
return_feature_count (
bool, defaultFalse) – WhenTrue, also fetches the feature count for each discovered layer (requires extra HTTP requests per layer).- Returns:
List of discovered service entries, each carrying
name,url,type, and parsedmetadata.- Return type:
list[CrawlServiceEntry]
Notes
After a successful call, the following instance attributes are populated:
services— the returned list.report— the fullCrawlReport.services_with_feature_count— same as services when return_feature_count wasTrue.
- filter_directory_layers(layer_type)[source]¶
Filter discovered layers by type.
- Parameters:
layer_type (
str) – The layer type string to match (e.g."Feature Layer","Raster Layer").- Returns:
Metadata entries for layers whose
typematches layer_type.- Return type:
list[LayerMetadata]- Raises:
ValueError – If
crawl()has not been called yet.
See also
feature_layersShortcut for
filter_directory_layers("Feature Layer").rastersShortcut for
filter_directory_layers("Raster Layer").
Token session¶
- class restgdf.ArcGISTokenSession(session, credentials=None, token_url='https://www.arcgis.com/sharing/rest/generateToken', token_refresh_threshold=60, token=None, expires=None, verify_ssl=True, config=None)[source]¶
Bases:
objectWrap an aiohttp session with ArcGIS token refresh behavior.
Construction knobs (
token_url,token_refresh_threshold,credentials) are validated viaTokenSessionConfigin__post_init__()so a bogus scheme or zero-length username fails fast withRestgdfResponseErrorrather than surfacing as a 401 or anaiohttperror deep in the request path.- session: ClientSession¶
- credentials: AGOLUserPass | None = None¶
- config: TokenSessionConfig | None = None¶
- property expires_at: datetime | None¶
Return the token expiry as a tz-aware UTC
datetime.ArcGIS returns
expiresin either seconds or milliseconds since the Unix epoch — values above1e11are treated as milliseconds and divided by 1000. ReturnsNonewhen no expiry is set.
- update_dict(input_dict=None)[source]¶
Return a request payload/query dict merged with the active token.
- async update_token()[source]¶
Update the token by making a request to the token URL.
The
/generateTokenpayload is validated againstTokenResponse(strict tier) so malformed/error envelopes raiseRestgdfResponseErrorinstead ofKeyErrordeep in caller code paths.Retries up to
_MAX_TOKEN_RETRIEStimes with exponential backoff (base_BASE_BACKOFF_S) on transient network errors. Deterministic errors (bad credentials, content-type mismatches, validation failures) are re-raised immediately. After exhausting retries, raisesTokenRefreshFailedError.Emits structured log events: *
auth.refresh.start— before the POST *auth.refresh.success— after successful token update *auth.refresh.failure— on any exception
- async update_token_if_needed()[source]¶
Ensure the token is valid and refresh if necessary.
BL-03: concurrent callers racing on an expired token collapse onto a single
/generateTokenPOST via a lazily-initialized per-instanceasyncio.Lockwith a double-checkedtoken_needs_update()inside the lock (plan.md §3c R-18, kickoff phase-1a §10.4). The lock is created here — not in__post_init__— so instances constructed outside a running event loop (e.g. at import time or inside a sync test) never triggerDeprecationWarning: There is no current event loop.
- async get(url, params=None, headers=None, **kwargs)[source]¶
Make a GET request to the specified URL with the token.
- async post(url, data=None, headers=None, **kwargs)[source]¶
Make a POST request to the specified URL with the token.
- property closed: bool¶
Return
Truewhen the underlyingaiohttp.ClientSessionis closed.Delegating lets
ArcGISTokenSessionsatisfy the internalAsyncHTTPSessiontransport Protocol uniformly withaiohttp.ClientSession(R-71).
- async close()[source]¶
Close the underlying
aiohttp.ClientSession.Mirrors
aiohttp.ClientSession.close()so token sessions and raw aiohttp sessions are interchangeable through the internalAsyncHTTPSessiontransport Protocol. Idempotent: closing an already-closed session is a no-op.
Errors¶
- exception restgdf.RestgdfResponseError(message, *, model_name='', context='', raw=None, url=None, status_code=None, request_id=None)[source]¶
Bases:
RestgdfError,ValueErrorRaised when validated ArcGIS response handling must fail fast.
- Variables:
model_name – The pydantic model class name associated with the failed parse (for example
"CountResponse"or"LayerMetadata").context – A short identifier describing where the response came from (for example the request URL or a helper name). Used by operators triaging ArcGIS vendor variance.
raw – The raw JSON-decoded payload that failed validation. Kept on the exception so callers can log or re-raise without re-reading the response body.
Canonical exception taxonomy for restgdf 3.0.
This module defines the public exception hierarchy used by every public
entry point in restgdf. All domain-specific exceptions derive from
RestgdfError so callers can catch “any restgdf failure” with a
single except RestgdfError block while still being able to discriminate
between transport, schema, auth, pagination, configuration, and conversion
failures via the more specific subclasses.
Several classes multi-inherit from a builtin exception in addition to their restgdf-specific parent. This is deliberate and preserves backward-compat:
ConfigurationError(RestgdfError, ValueError)keepsexcept ValueErrorcallers working while restgdf 3.x stabilizes (R-09).OptionalDependencyError(ConfigurationError, ModuleNotFoundError)keepsexcept ImportError/except ModuleNotFoundErrorworking when optional pandas/geopandas/pyogrio dependencies are missing.RestgdfResponseError(RestgdfError, ValueError)keeps the 2.xexcept ValueErrorcontract around typed response validation.PaginationError(ArcGISServiceError, IndexError)preserves the 2.x “looks like an IndexError” contract around cursor exhaustion.AuthenticationError(RestgdfResponseError, PermissionError)lets callers treat auth failures asPermissionErrorwhen appropriate.RestgdfTimeoutError(TransportError, TimeoutError)keepsexcept TimeoutErrorcallers working on request timeouts without shadowing the builtinTimeoutErrorsymbol.
Hierarchy:
RestgdfError(Exception)
+-- ConfigurationError(RestgdfError, ValueError)
| +-- OptionalDependencyError(ConfigurationError, ModuleNotFoundError)
+-- RestgdfResponseError(RestgdfError, ValueError)
| +-- SchemaValidationError(RestgdfResponseError)
| | +-- FieldDoesNotExistError(SchemaValidationError)
| +-- ArcGISServiceError(RestgdfResponseError)
| | +-- PaginationError(ArcGISServiceError, IndexError)
| +-- AuthenticationError(RestgdfResponseError, PermissionError)
| +-- InvalidCredentialsError(AuthenticationError)
| +-- TokenExpiredError(AuthenticationError)
| +-- TokenRequiredError(AuthenticationError)
| +-- TokenRefreshFailedError(AuthenticationError)
| +-- AuthNotAttachedError(AuthenticationError)
+-- TransportError(RestgdfError)
| +-- RestgdfTimeoutError(TransportError, TimeoutError)
| +-- RateLimitError(TransportError)
+-- OutputConversionError(RestgdfError)
- exception restgdf.errors.ArcGISServiceError(message, *, model_name='', context='', raw=None, url=None, status_code=None, request_id=None)[source]¶
Bases:
RestgdfResponseErrorRaised when the ArcGIS service returns an explicit
{"error": ...}envelope.
- exception restgdf.errors.AuthNotAttachedError(message, *, context=None, attempt=None, cause=None, model_name='AuthenticationError', raw=None)[source]¶
Bases:
_AuthSubtypeBaseRaised when a 499 is observed — the library did not attach auth to the request.
Per R-14 no retry is attempted; the error propagates immediately to the caller. This is semantically distinct from
TokenExpiredError(498) which does trigger a single-flight refresh.
- exception restgdf.errors.AuthenticationError(message, *, model_name='', context='', raw=None, url=None, status_code=None, request_id=None)[source]¶
Bases:
RestgdfResponseError,PermissionErrorRaised when ArcGIS auth (token, creds, scope) is invalid or expired.
Multi-inherits
PermissionErrorsoexcept PermissionErrorin application code can treat restgdf auth failures uniformly with local-filesystem permission failures.
- exception restgdf.errors.ConfigurationError[source]¶
Bases:
RestgdfError,ValueErrorRaised when restgdf configuration (env vars, Settings, kwargs) is invalid.
Multi-inherits
ValueErrorthrough 3.x so existingexcept ValueErrorcallers continue to catch misconfiguration. TheValueErrorbase will be dropped in 3.1+.
- exception restgdf.errors.FieldDoesNotExistError(field_name=None, *, context=None, message=None)[source]¶
Bases:
SchemaValidationErrorA referenced field is absent from the ArcGIS layer metadata (BL-09).
Replaces the 2.x
FIELDDOESNOTEXISTIndexErrorsingleton per plan.md §3c R-02. Callers previously catchingIndexErrormust migrate toexcept FieldDoesNotExistError(or the parentSchemaValidationError/RestgdfResponseError). No compat shim.- Variables:
field_name (:py:class:
`str | tuple[str`, :py:class:`...] | None`) – The field(s) that failed resolution.context (
str) – Call-site identifier (e.g."FeatureLayer.get_unique_values"); defaults to"FieldDoesNotExistError"when the caller passesNone, matching the parentRestgdfResponseErrorcontract wherecontextis always a non-Nonestring.
- exception restgdf.errors.InvalidCredentialsError(message, *, context=None, attempt=None, cause=None, model_name='AuthenticationError', raw=None)[source]¶
Bases:
_AuthSubtypeBaseRaised on 400 / bad credentials from
/generateToken.Inherits
AuthenticationError→PermissionError.
- exception restgdf.errors.OptionalDependencyError[source]¶
Bases:
ConfigurationError,ModuleNotFoundErrorRaised when an optional dependency (pandas/geopandas/pyogrio) is absent.
Multi-inherits
ModuleNotFoundErrorso existingexcept ImportError/except ModuleNotFoundErrorcall sites keep working whenrestgdf[geo]is not installed.
- exception restgdf.errors.OutputConversionError[source]¶
Bases:
RestgdfErrorRaised when converting validated ArcGIS data to a GeoDataFrame / DataFrame fails.
- exception restgdf.errors.PaginationInconsistencyWarning[source]¶
Bases:
UserWarningEmitted when an ArcGIS batch response is self-inconsistent (R-73).
Specifically: a page that returns zero features and sets
exceededTransferLimit=trueis an ArcGIS-side pagination bug — the cursor cannot advance (offset-based pagination needs at least one row per page to progress) but the service simultaneously insists more rows exist. Left un-flagged this produces a silently-truncated result set.Multi-inherits
UserWarningso callers can silence or escalate it viawarnings(e.g.warnings.filterwarnings("error", category=PaginationInconsistencyWarning)).
- exception restgdf.errors.PaginationError(*args, batch_index=None, page_size=None)[source]¶
Bases:
ArcGISServiceError,IndexErrorRaised when cursor-based pagination cannot advance or exceeds limits.
Multi-inherits
IndexErrorso legacy call sites that usedexcept IndexErroraround pagination exhaustion keep working.- Variables:
batch_index – The zero-based batch index at which pagination failed, if known.
page_size – The page size in effect when pagination failed, if known.
- exception restgdf.errors.RateLimitError(*args, retry_after=None, url=None, status_code=None)[source]¶
Bases:
TransportErrorRaised when the ArcGIS service signals a rate limit / throttle.
- Variables:
retry_after – Optional seconds to wait before retrying, parsed from a
Retry-Afterheader or service envelope.Nonewhen the service did not supply a hint.
- exception restgdf.errors.RestgdfError[source]¶
Bases:
ExceptionBase class for every exception raised by
restgdf.
- exception restgdf.errors.RestgdfResponseError(message, *, model_name='', context='', raw=None, url=None, status_code=None, request_id=None)[source]¶
Bases:
RestgdfError,ValueErrorRaised when validated ArcGIS response handling must fail fast.
- Variables:
model_name – The pydantic model class name associated with the failed parse (for example
"CountResponse"or"LayerMetadata").context – A short identifier describing where the response came from (for example the request URL or a helper name). Used by operators triaging ArcGIS vendor variance.
raw – The raw JSON-decoded payload that failed validation. Kept on the exception so callers can log or re-raise without re-reading the response body.
- exception restgdf.errors.RestgdfTimeoutError(*args, url=None, status_code=None, timeout_kind=None)[source]¶
Bases:
TransportError,TimeoutErrorRaised when a request times out.
Named
RestgdfTimeoutError(notTimeoutError) to avoid shadowing the builtin. Multi-inheritsTimeoutErrorsoexcept TimeoutErrorcallers continue to match.- Variables:
timeout_kind – One of
"total","connect", or"read", indicating which timeout budget was exceeded.Nonewhen unknown.
- exception restgdf.errors.SchemaValidationError(message, *, model_name='', context='', raw=None, url=None, status_code=None, request_id=None)[source]¶
Bases:
RestgdfResponseErrorRaised when an ArcGIS response envelope fails schema validation.
Does not multi-inherit
IndexError: R-02 explicitly forbids the transitionalSchemaValidationError(IndexError, ...)shim that earlier drafts of the plan proposed.
- exception restgdf.errors.TokenExpiredError(message='Token expired (Esri 498)', *, code=498, context=None, attempt=None, cause=None)[source]¶
Bases:
_AuthSubtypeBaseRaised when ArcGIS returns error code 498 (Invalid Token).
- Variables:
code (
int) – Always498.
- exception restgdf.errors.TokenRefreshFailedError(message, *, context=None, attempt=None, cause=None, model_name='AuthenticationError', raw=None)[source]¶
Bases:
_AuthSubtypeBaseRaised after the bounded-retry ladder for
/generateTokenis exhausted.- Variables:
attempt (
int | None) – The final attempt number at which the refresh was abandoned.
- exception restgdf.errors.TokenRequiredError(message, *, context=None, attempt=None, cause=None, model_name='AuthenticationError', raw=None)[source]¶
Bases:
_AuthSubtypeBaseRaised when ArcGIS returns error code 499 (Token Required).
Semantically: the service demands a token but the request did not carry one (or the wrong transport was chosen).
- exception restgdf.errors.TransportError(*args, url=None, status_code=None)[source]¶
Bases:
RestgdfErrorRaised for network/HTTP transport-layer failures (connection, DNS, …).
- Variables:
url – The URL that was being requested when the failure occurred.
status_code – The HTTP status code, if one was received before the transport failure.
Nonefor pre-connect failures (DNS, refused, …).
Runtime settings¶
See Pydantic models for the Settings model; the helpers below
read it from the environment.
- restgdf.get_settings()[source]¶
Return the process-wide cached
Settingsinstance.Deprecated since version phase-2a: Use
restgdf.get_config()andrestgdf.Config. This shim constructs aSettingsfrom the cachedConfigand emits a singleDeprecationWarningper process.
Migration helpers¶
Compatibility helpers for the 1.x → 2.x migration.
Downstream code that indexed the legacy dict-based public surface (for
example metadata["name"], crawl_result["services"]) needs a
short-term way to keep working during its own upgrade window. These
helpers convert the 2.x pydantic models back into plain Python
structures on demand.
They are migration aids, not the primary API — prefer direct
attribute access (metadata.name) and model_dump() in new code.
These helpers will stay available for the 2.x series but may be removed
in 3.x.
- restgdf.compat.as_dict(obj)[source]¶
Return a plain Python dict view of a restgdf pydantic model.
If
objis apydantic.BaseModelinstance, returnsobj.model_dump(mode="python", by_alias=False)— a dict keyed by the model’s Python (snake_case) field names, with nested models also recursively dumped.If
objis anything else (already-a-dict,None, primitive, list), it is returned unchanged. This lets migration code wrap heterogeneous values uniformly:for entry in report.services: row = as_dict(entry) # dict whether entry is model or already dict save(row["name"], row.get("url"))
This helper is intentionally conservative: it does not recurse into containers of models and does not coerce
by_alias=True. Callers that need the ArcGIS-native camelCase round-trip should callmodel_dump()explicitly.
- restgdf.compat.as_json_dict(obj)[source]¶
Return a JSON-safe dict view of a restgdf pydantic model.
Like
as_dict(), but usesmodel_dump(mode="json")so every nested value is a JSON-serializable primitive (SecretStr→"**********"placeholder,datetime→ ISO string, etc.). Handy for structured logging of a model without carrying unserializable objects into the log record.Non-model values are returned unchanged.