Authoritative tooling for creating OGC API - EDR Part 3 Service Profiles
Project description
OGC API - EDR Part 3 Service Profile Generator
Authoritative tooling for creating OGC API - Environmental Data Retrieval (EDR) Part 3 Service Profiles, built on Pydantic and edr-pydantic.
Overview
Profile structure is defined as Pydantic models (src/models.py). Instantiating a ServiceProfile validates the entire profile — enums enforce normative OGC values, cross-model validators catch referential errors — before any files are written.
Collections use edr-pydantic's authoritative Collection model directly, meaning a profile config is simultaneously a valid EDR collection descriptor and a Part 3 profile definition.
Installation
pip install ogc-edr-profile
Usage
Generate profile artifacts
ogc-edr-profile generate --config examples/water_gauge.yaml --output ./my_profile
Validate a config without generating output
ogc-edr-profile validate --config examples/water_gauge.yaml
Export the JSON Schema
ogc-edr-profile schema --output profile.schema.json
The schema can be used for editor autocompletion — point your YAML extension at profile.schema.json to get inline validation and suggestions while authoring configs.
Output
my_profile/
├── openapi.yaml
├── asyncapi.yaml # if pubsub is configured
├── profile_config.json # round-trip model export
├── requirements/
│ ├── requirements_class_core.adoc
│ └── core/REQ_<id>.adoc
└── abstract_tests/
├── ATS_class_core.adoc
└── core/ATS_<id>.adoc
Getting Started
The fastest way to create a profile is to copy the example and modify it:
cp examples/water_gauge.yaml my_profile.yaml
Then edit my_profile.yaml — at minimum change name, title, and the collection id. Validate as you go:
ogc-edr-profile validate --config my_profile.yaml
Once valid, generate:
ogc-edr-profile generate --config my_profile.yaml --output ./my_profile
If you prefer to build from scratch, the minimal valid config looks like this:
name: my_profile
title: My EDR Profile
collections:
- id: my_collection
links:
- href: https://example.com/collections/my_collection
rel: self
type: application/json
extent:
spatial:
bbox:
- [-180, -90, 180, 90]
crs: "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
parameter_names: {}
From there, add data_queries to declare which query types your collection supports, output_formats to declare response formats, requirements to define normative statements, and abstract_tests to define conformance tests. Each section is described in detail below.
Authoring a Profile Config
A profile config is a YAML or JSON file that defines a ServiceProfile. The full machine-readable schema is in profile.schema.json. Below is a field-by-field reference.
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
yes | Lowercase identifier using only a-z, 0-9, _. Used in OGC URIs, filenames, and OpenAPI operationIds. e.g. water_gauge |
title |
string |
yes | Human-readable profile title. e.g. Water Gauge Observations Profile |
version |
string |
no | Profile version. Defaults to 1.0 |
collections |
list |
yes | One or more EDR collections (see below) |
requirements |
list |
no | Normative requirements (see below) |
abstract_tests |
list |
no | Conformance tests — each must reference a valid requirement id (see below) |
pubsub |
object |
no | OGC API - EDR Part 2 PubSub configuration (see below) |
collections[]
Each collection uses the edr-pydantic Collection schema — the same model an EDR server returns at /collections/{id}. Key fields:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
yes | Collection identifier. e.g. water_gauge |
title |
string |
no | Human-readable collection name |
description |
string |
no | Collection description |
links |
list |
yes | At minimum a self link |
extent |
object |
yes | Spatial (and optionally temporal/vertical) extent |
extent.spatial.bbox |
list |
yes | Bounding box as [[minLon, minLat, maxLon, maxLat]] |
extent.spatial.crs |
string |
yes | CRS URI, typically http://www.opengis.net/def/crs/OGC/1.3/CRS84 |
data_queries |
object |
no | Which EDR query types this collection supports (see below) |
output_formats |
list |
no | Supported output format labels e.g. GeoJSON, CoverageJSON, CSV |
parameter_names |
object |
no | Map of parameter id → Parameter object describing observed properties |
data_queries
Each key is an EDR query type. Set it to enable that query type for the collection. Supported keys:
items · position · area · radius · cube · trajectory · corridor · locations · instances
Each value is an EDRQuery object with a link field:
data_queries:
position:
link:
href: https://example.com/collections/water_gauge/position
rel: data
variables:
query_type: position
output_formats:
- CoverageJSON
items:
link:
href: https://example.com/collections/water_gauge/items
rel: data
variables:
query_type: items
output_formats:
- GeoJSON
- CSV
parameter_names
Describes the observed properties the collection exposes. Each entry is a Parameter object:
parameter_names:
gauge_height:
type: Parameter
observedProperty:
label: Gauge Height
unit:
label: feet
symbol: ft
streamflow:
type: Parameter
observedProperty:
label: Streamflow
unit:
label: cubic feet per second
symbol: cfs
requirements[]
Normative requirements that implementations of this profile must satisfy. Each requirement becomes a REQ_<id>.adoc file and an entry in the requirements class.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
yes | Lowercase, hyphen-separated identifier. e.g. data-query-items-water-gauge. Must match pattern ^[a-z0-9][a-z0-9\-]*$ |
statement |
string |
yes | One-sentence normative statement of the requirement |
parts |
list[string] |
yes | One or more SHALL/MUST clauses that make up the requirement body |
requirements:
- id: data-query-items-water-gauge
statement: The water_gauge collection SHALL support the Items query type.
parts:
- The service SHALL provide a /collections/water_gauge/items endpoint.
- The Items query SHALL return a GeoJSON FeatureCollection.
abstract_tests[]
Conformance tests corresponding to requirements. Each test becomes an ATS_<id>.adoc file and an entry in the conformance class. Every requirement_id must match an existing requirement id — the model validator will reject the profile if not.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
yes | Must equal requirement_id |
requirement_id |
string |
yes | The id of the requirement this test validates |
steps |
list[string] |
yes | Ordered test steps |
abstract_tests:
- id: data-query-items-water-gauge
requirement_id: data-query-items-water-gauge
steps:
- Send GET request to /collections/water_gauge/items.
- Verify the response is a valid GeoJSON FeatureCollection.
pubsub
Optional. Configures OGC API - EDR Part 2 (PubSub) output. When present, an asyncapi.yaml is generated.
| Field | Type | Default | Description |
|---|---|---|---|
broker_host |
string |
localhost |
Message broker hostname |
broker_port |
integer |
5672 |
Broker port (1–65535) |
protocol |
string |
amqp |
One of amqp, mqtt, kafka |
filters |
list |
[] |
Subscription filters (see below) |
pubsub.filters[]
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
yes | Filter parameter name |
description |
string |
yes | What the filter does |
type |
string |
no | One of string, number, array, boolean. Defaults to string |
pubsub:
broker_host: localhost
broker_port: 5672
protocol: amqp
filters:
- name: state
description: Filter by US state abbreviation.
type: string
- name: threshold_ft
description: Only notify when gauge height exceeds this value.
type: number
See examples/water_gauge.yaml for a complete working config.
Programmatic Use
from ogc_edr_profile.models import ServiceProfile
from ogc_edr_profile.generate import generate
from pathlib import Path
profile = ServiceProfile.model_validate(config_dict)
generate(profile, Path("./output"))
Repository Structure
├── src/
│ ├── models.py # Authoritative Pydantic schema
│ ├── generate.py # Serialization: validated model → OpenAPI, AsyncAPI, AsciiDoc
│ └── cli.py # CLI entry point
├── examples/
│ └── water_gauge.yaml # Complete example profile config
├── profile.schema.json # Machine-readable JSON Schema for profile configs
└── pyproject.toml
Standards
- OGC API - EDR Part 1: Core
- OGC API - EDR Part 2: PubSub
- OGC API - EDR Part 3: Service Profiles (draft)
- OpenAPI 3.0 / AsyncAPI 3.0
- Metanorma/AsciiDoc documentation format
License
Apache License 2.0 — See LICENSE for details.
Contact
- Author: Shane Mill (NOAA/NWS/MDL)
- Email: shane.mill@noaa.gov
- Issues: https://github.com/ShaneMill1/OGC-Service-Profile-Creation/issues
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ogc_edr_profile-1.0.2.tar.gz.
File metadata
- Download URL: ogc_edr_profile-1.0.2.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18a9766987cce72b4ff9048c75e84eb91d52d9358ff38d9bbb3a02c6b3353caa
|
|
| MD5 |
da6cced6139e4797de08479bb499a6fd
|
|
| BLAKE2b-256 |
091dd4c1d9d23754b5467db74f633b3fbce3b5e0bfd078b106c33ce9e81ad4d0
|
File details
Details for the file ogc_edr_profile-1.0.2-py3-none-any.whl.
File metadata
- Download URL: ogc_edr_profile-1.0.2-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d947926732e668d951fd45f1cf2554c2dc5559da458c4b3c09ec7b7976df9e72
|
|
| MD5 |
a2e9192a45d354df564765e9d25a21b0
|
|
| BLAKE2b-256 |
31e7faeca2728ee5ae4936999b1a97926a5c2b5dfe110f14f6ad096d049996f4
|