pydantic-ogcapi
Pydantic v2 models for the OGC API - Features standards, extending pydantic-geojson.
The GeoJSON Feature and FeatureCollection models subclass their
pydantic_geojson counterparts, so all RFC 7946 geometry validation is
inherited unchanged; this package adds the members OGC API layers on top.
Installation
pip install pydantic-ogcapi
Usage
Every public name is re-exported from the package root, so a single import is usually enough:
from pydantic_ogcapi import Collection, FeatureCollection, Link
collection = Collection(
id="buildings",
title="Buildings",
links=[Link(href="/collections/buildings/items", rel="items")],
)
collection.model_dump()
# {'id': 'buildings', 'links': [...], 'title': 'Buildings',
# 'itemType': 'feature', 'crs': ['http://www.opengis.net/def/crs/OGC/1.3/CRS84']}
The per-part modules stay importable when that reads more clearly:
from pydantic_ogcapi.core import LandingPage
from pydantic_ogcapi.crs import CrsParameters
from pydantic_ogcapi.filtering import Queryables
from pydantic_ogcapi.transaction import TransactionResponse
Naming
Models declare snake_case attributes and serialise to the camelCase (and, for some query parameters, kebab-case) member names the standards define. Both spellings are accepted when parsing:
fc = FeatureCollection.model_validate({"type": "FeatureCollection", "features": [], "numberMatched": 127})
fc.number_matched # 127
fc.model_dump()["numberMatched"] # 127
model_dump() and model_dump_json() default to by_alias=True and
exclude_none=True, so output carries the wire names and omits members that
were never set — OGC responses distinguish an absent member from a null one.
Parsing query parameters
from pydantic_ogcapi import BoundingBox, DatetimeInterval
DatetimeInterval.parse("2018-02-12T00:00:00Z/..") # half-open interval
BoundingBox.parse("-180,-90,180,90") # 2D bounding box
Layout
| Module | Standard | Contents |
|---|---|---|
pydantic_ogcapi.core |
Part 1: Core (17-069r4) | LandingPage, ConformanceDeclaration, Collection, Collections, Extent, Feature, FeatureCollection, Link, query parameters |
pydantic_ogcapi.crs |
Part 2: CRS by Reference (18-058) | CrsParameters, Content-Crs helpers |
pydantic_ogcapi.filtering |
Part 3: Filtering (19-079r2) | Queryables, Functions, FilterParameters, CQL2 constants |
pydantic_ogcapi.transaction |
Part 4: CRUD (20-002, draft) | TransactionResponse, ConditionalHeaders, TransactionStatus |
Well-known URIs (CRS84, GREGORIAN_TRS) and the conformance class URIs
(CONF_CORE, CONF_CRS, CONF_FILTER, …) are exported from the root too.
Notes on the standards
A few details that are easy to get wrong, and which the models encode:
- The
/collectionsresponse has notimeStamp/numberMatched/numberReturned; those belong only to the GeoJSON feature collection. Linkin Features Part 1 has notemplated/varBase, and the landing page has noattribution— those come from OGC API - Common. Extra members are allowed and round-trip, so a server that sends them still works.- The temporal reference system URI lives under
/def/uom/:http://www.opengis.net/def/uom/ISO-8601/0/Gregorian. - A spatial queryable omits
typeand usesformatinstead. - Part 4 defines no new response bodies; its outcome is the status code plus
the
Location,ETagandLast-Modifiedheaders.
Development
pip install -e ".[dev]"
pytest
Releasing
The version is single-sourced from __version__ in
src/pydantic_ogcapi/__init__.py; pyproject.toml reads it from there.
- Bump
__version__and merge that tomain. - Publish a GitHub Release tagged
v<version>(for examplev0.1.0).
That triggers the publish workflow, which builds the sdist and wheel,
verifies the tag matches __version__, and uploads to PyPI via trusted
publishing. To rehearse first, run the workflow manually from the Actions tab
and choose the testpypi target.
Publishing is irreversible — a version number cannot be reused on PyPI even after a release is deleted — so the workflow never runs on an ordinary push.
License
Licensed under the Apache License, Version 2.0.
Metadata
Release files for pydantic-ogcapi 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydantic_ogcapi-0.1.0.tar.gz | 22.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydantic_ogcapi-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.5 kB
Release files / pydantic_ogcapi-0.1.0.tar.gz
| Download URL | pydantic_ogcapi-0.1.0.tar.gz |
|---|---|
| Size | 22.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
344d46854628ea4fd8d362b0beb66f91002c7866d4d0f582f1d9ab4296f8fc90
|
|
BLAKE2b-256 checksum How to use checksums |
8c105c24a2de8f311a040e34ab9d1e5db23f728b181693bedd471d2a18a31685
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / pydantic_ogcapi-0.1.0-py3-none-any.whl
| Download URL | pydantic_ogcapi-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
56cb03b6b58a4b1f1808baa3bf94c2b75aea240597e10e3c5adf9488827d9847
|
|
BLAKE2b-256 checksum How to use checksums |
ad25885446b8cb00fc53261a83b63fd122f9922de2f509e2ecbbe01fdb5fa6dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log