Skip to main content

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/ogc_edr_profile/models.py). Instantiating a ServiceProfile validates the entire profile — 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

Workflow

1. Author a Profile Config

A profile config is a YAML or JSON file. Start with the minimal example:

cp examples/minimal_profile.yaml my_profile.yaml

The minimal valid config:

name: my_profile
title: My EDR Profile

# OGC API - EDR Part 3 compliance fields (recommended)
required_conformance_classes:
  - "http://www.opengis.net/spec/ogcapi-edr-1/1.0/conf/core"

extent_requirements:
  minimum_bbox: [-180, -90, 180, 90]
  allowed_crs:
    - "http://www.opengis.net/def/crs/OGC/1.3/CRS84"

output_formats:
  - name: GeoJSON
    media_type: application/geo+json
    schema_ref: https://geojson.org/schema/FeatureCollection.json

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:
      temp:
        type: Parameter
        observedProperty:
          label: Temperature
        unit:              # REQUIRED per OGC API - EDR Part 3
          label: Celsius
          symbol: C

See examples/minimal_profile.yaml for a complete working example and examples/nwsviz_profile.yaml for a full profile with 13 collections, 3 processes, requirements, abstract tests, and document metadata.

2. Generate Profile Artifacts

ogc-edr-profile generate \
  --config my_profile.yaml \
  --output ./my_profile

Produces:

my_profile/
├── openapi.yaml
├── profile_config.json
├── document.adoc                        # Metanorma root document
├── sections/
│   ├── 00-abstract.adoc
│   ├── 01-preface.adoc
│   ├── 02-scope.adoc
│   ├── 03-conformance.adoc
│   ├── 04-references.adoc
│   ├── 05-terms.adoc
│   ├── 06-requirements.adoc
│   └── 07-abstract-tests.adoc
├── requirements/
│   ├── requirements_class_core.adoc
│   └── core/REQ_<id>.adoc
└── abstract_tests/
    ├── ATS_class_core.adoc
    └── core/ATS_<id>.adoc

Validate a config without generating output:

ogc-edr-profile validate --config my_profile.yaml

3. Compile OGC PDF

Requires Docker. Shells out to the official metanorma/metanorma image — no Ruby or LaTeX install needed.

ogc-edr-profile generate \
  --config my_profile.yaml \
  --output ./my_profile \
  --pdf

The document_metadata block in the profile config drives the Metanorma document header:

document_metadata:
  doc_number: "24-nwsviz"
  doc_subtype: implementation
  copyright_year: 2026
  editors:
    - Shane Mill
  submitting_orgs:
    - NOAA/NWS/MDL
  keywords:
    - ogcdoc
    - OGC API
    - EDR
    - NWSViz
    - service profile
  external_id: http://www.opengis.net/doc/dp/ogcapi-edr-nwsviz/1.0

Produces my_profile/document.pdf — a fully compliant OGC draft-standard PDF with Abstract, Preface, Scope, Conformance, References, Terms, Requirements class, and normative Abstract Test Suite annex.

4. Validate Against a Live Server

ogc-edr-profile validate-server \
  --config my_profile.yaml \
  --url https://edr-api-desi-c.mdl.nws.noaa.gov \
  --max-examples 3

Results:

Operations:  100 selected / 106 total
Tested:      47
Test cases:  1002 generated, 1002 passed

No issues found in 49.51s

Use --stateful to additionally test job lifecycle endpoints (/jobs/{jobId}, DELETE /jobs/{jobId}) via POST /execution chaining.

Add collection_examples to your config to supply real instanceId values for schemathesis path parameters:

collection_examples:
  my_collection:
    instanceId: "2025-04-02T00:00:00Z"

5. OGC CITE Conformance Testing

EDR Conformance Testing

Run the official OGC API - EDR Part 1 conformance test suite (ets-ogcapi-edr10):

ogc-edr-profile cite-test \
  --url https://edr-api-desi-c.mdl.nws.noaa.gov \
  --report ./cite_results

Results:

OGC API - EDR CITE Results
  Passed:  76/84
  Failed:  0
  Skipped: 8

✓ All CITE tests passed.

The tool automatically:

  • Clones and builds ets-ogcapi-edr10 from GitHub on first run
  • Caches Docker image (ogccite/ets-ogcapi-edr10:local) for subsequent runs
  • Runs TestNG tests via docker exec
  • Supports localhost testing with --network host mode
  • Generates JSON report with detailed test results

The skipped tests are optional features not implemented by the server.

Features Conformance Testing

Run the official OGC API - Features Part 1 conformance test suite (ets-ogcapi-features10):

ogc-edr-profile cite-test-features \
  --url https://api.example.com \
  --report ./cite_features_results

Results:

OGC API - Features CITE Results
  Passed:  639/712
  Failed:  18
  Skipped: 55

✗ 18 test(s) failed.

The tool automatically:

  • Pulls pre-built Docker image (ogccite/ets-ogcapi-features10:latest) from Docker Hub
  • Runs TestNG tests via docker exec
  • Supports localhost testing with --network host mode
  • Generates JSON report with detailed test results

The skipped tests are optional features not implemented by the server.


Config Reference

Top-level fields

Field Type Required Description
name string yes Lowercase identifier using only a-z, 0-9, _. Used in OGC URIs and OpenAPI operationIds. e.g. water_gauge
title string yes Human-readable profile title
version string no Profile version. Defaults to 1.0
server_url string no Base URL of the live server (for documentation only - not used in profile OpenAPI per OGC API - EDR Part 3)
collections list yes One or more EDR collections (see below)
processes list no OGC API Processes to include in the OpenAPI (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)
collection_examples object no Map of collection id → example parameter values (e.g. instanceId) for server validation
document_metadata object no Metanorma document header fields for PDF compilation (see below)
required_conformance_classes list[string] no Conformance classes that implementations must declare. Defaults to EDR Core
extent_requirements object no Profile-level extent restrictions (see below)
output_formats list no Profile-level output format definitions with schema references (see below)
collection_id_pattern string no Regex pattern for valid collection IDs

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
title string no Human-readable collection name
description string no Collection description
links list yes At minimum a self link
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
output_formats list no Supported output format labels e.g. GeoJSON, CoverageJSON
parameter_names object no Map of parameter id → Parameter object

data_queries

Supported keys: items · position · area · radius · cube · trajectory · corridor · locations · instances

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

parameter_names

Note: Per OGC API - EDR Part 3 requirements, all parameters must specify unit and observedProperty. The tool validates this automatically.

parameter_names:
  gauge_height:
    type: Parameter
    observedProperty:
      label: Gauge Height
    unit:
      label: feet
      symbol: ft

extent_requirements

Profile-level extent restrictions per OGC API - EDR Part 3 REQ_extent.

Field Type Required Description
minimum_bbox list[float] yes Minimum spatial bounds [minLon, minLat, maxLon, maxLat]
allowed_crs list[string] no Enumerated list of valid CRS values
crs_pattern string no Regular expression defining valid CRS string patterns
allowed_trs list[string] no Enumerated list of valid TRS values
trs_pattern string no Regular expression defining valid TRS string patterns
allowed_vrs list[string] no Enumerated list of valid VRS values
vrs_pattern string no Regular expression defining valid VRS string patterns

Note: Either allowed_crs or crs_pattern must be specified.

extent_requirements:
  minimum_bbox: [-180, -90, 180, 90]
  allowed_crs:
    - "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
    - "http://www.opengis.net/def/crs/EPSG/0/4326"
  allowed_trs:
    - "http://www.opengis.net/def/uom/ISO-8601/0/Gregorian"

output_formats[]

Profile-level output format definitions with schema references per OGC API - EDR Part 3 REQ_output-format.

Field Type Required Description
name string yes Format name (e.g., GeoJSON, CoverageJSON)
media_type string yes MIME type (e.g., application/geo+json)
schema_ref string no URL to schema definition
output_formats:
  - name: GeoJSON
    media_type: application/geo+json
    schema_ref: https://geojson.org/schema/FeatureCollection.json
  - name: CoverageJSON
    media_type: application/prs.coverage+json
    schema_ref: https://schemas.opengis.net/ogcapi/edr/1.0/openapi/schemas/coverageJSON.yaml

required_conformance_classes[]

Conformance classes that implementations must declare at /conformance per OGC API - EDR Part 3 REQ_api.

Defaults to:

required_conformance_classes:
  - "http://www.opengis.net/spec/ogcapi-edr-1/1.0/conf/core"

Add additional conformance classes as needed:

required_conformance_classes:
  - "http://www.opengis.net/spec/ogcapi-edr-1/1.0/conf/core"
  - "http://www.opengis.net/spec/ogcapi-edr-1/1.0/conf/oas30"
  - "http://www.opengis.net/spec/ogcapi-edr-2/1.0/conf/pubsub"

processes[]

OGC API Processes to expose in the generated OpenAPI. Each entry produces /processes/{id} and /processes/{id}/execution paths, plus /processes, /jobs, /jobs/{jobId}, and /jobs/{jobId}/results.

Field Type Required Description
id string yes Process identifier e.g. edr-zarr-difference
title string no Human-readable process name
description string no Process description
output_content object no OpenAPI content map for the 200 response. Defaults to application/json
processes:
  - id: edr-zarr-difference
    title: EDR Zarr Dataset Difference
    description: Calculates the difference between two EDR Zarr datasets.
    output_content:
      application/zip:
        schema:
          type: object

requirements[]

Field Type Required Description
id string yes Lowercase, hyphen-separated. Must match ^[a-z0-9][a-z0-9\-]*$
statement string yes One-sentence normative statement
parts list[string] yes One or more SHALL/MUST clauses
requirements:
  - id: position-coveragejson
    statement: The position query SHALL return CoverageJSON.
    parts:
      - The service SHALL provide a /collections/{id}/position endpoint.
      - The response Content-Type SHALL be application/prs.coverage+json.

abstract_tests[]

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: position-coveragejson
    requirement_id: position-coveragejson
    steps:
      - Send GET request to /collections/{id}/position?coords=POINT(lon lat).
      - Verify the response Content-Type is application/prs.coverage+json.

pubsub

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

Each filter: name (required), description (required), type (one of string, number, array, boolean, default string).


document_metadata

Controls the Metanorma document header when compiling a PDF with --pdf.

Field Type Required Description
doc_number string yes OGC document number e.g. 24-nwsviz
doc_subtype string yes One of implementation, best-practice, engineering-report
editors list[string] yes Editor names
submitting_orgs list[string] yes Submitting organization names
keywords list[string] no Document keywords
copyright_year integer no Defaults to current year
external_id string no OGC external document URI

OGC API - EDR Part 3 Compliance

This tool implements the requirements of OGC API - EDR Part 3: Service Profiles (draft standard):

Key Compliance Features

  1. Profile OpenAPI Document (REQ_publishing)

    • Generated OpenAPI has empty servers array (profile is implementation-independent)
    • Landing page schema requires profile link relation
    • Profile URI advertised in x-ogc-profile info field
  2. Conformance Classes (REQ_api)

    • /conformance endpoint schema specifies required conformance classes
    • Defaults to EDR Core, customizable via required_conformance_classes
  3. Parameter Names (REQ_parameter-names)

    • Validates that all parameters specify unit and observedProperty
    • Automatically enforced during profile validation
  4. Extent Requirements (REQ_extent)

    • Profile-level extent_requirements specify minimum bounds
    • CRS/TRS/VRS restrictions via enumerated lists or regex patterns
  5. Output Formats (REQ_output-format)

    • Profile-level output_formats with schema references
    • Links to JSON Schema, XML Schema, or format specifications
  6. Pub/Sub (REQ_pubsub)

    • Automatically adds Part 2 conformance requirement when pubsub is present
    • AsyncAPI document specifies channels and payloads

Profile Types

The tool supports both:

  • Class 1 Profiles: Restrictive profiles that constrain EDR Core
  • Class 2 Profiles: Extended profiles that add custom requirements (e.g., processes)

Both remain compliant with EDR Core - extensions are optional, not mandatory.


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/
│   └── ogc_edr_profile/
│       ├── models.py            # Authoritative Pydantic schema
│       ├── generate.py          # Validated model → OpenAPI, AsyncAPI, AsciiDoc
│       ├── compile.py           # PDF compilation via metanorma/metanorma Docker image
│       ├── cite.py              # OGC CITE test suite orchestration
│       └── cli.py               # CLI entry point
├── examples/
│   ├── water_gauge.yaml         # Minimal example profile config
│   └── nwsviz_profile.yaml      # Full NWSViz profile: 13 collections, 3 processes, PDF metadata
├── 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)
  • OGC API - Processes Part 1
  • OpenAPI 3.0 / AsyncAPI 3.0
  • Metanorma/AsciiDoc documentation format

License

MIT — See LICENSE for details.

Contact

Metadata

Release files for ogc-edr-profile 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ogc-edr-profile 2.0.0
File Size Uploaded
ogc_edr_profile-2.0.0.tar.gz 32.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ogc-edr-profile 2.0.0
File Interpreter ABI Platform
ogc_edr_profile-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 69.0 kB

Release files / ogc_edr_profile-2.0.0.tar.gz

Download URL ogc_edr_profile-2.0.0.tar.gz
Size 32.5 kB
Tags Source
SHA-256 checksum
How to use checksums
029d86d4017e50f4c2f0194a81749da20ab4d4c3f11b6fa23e7be1094ebeed75
BLAKE2b-256 checksum
How to use checksums
6d24b120180bc26b524f085a5945d92d6234cc826fb29b6da0af776b12f93466
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / ogc_edr_profile-2.0.0-py3-none-any.whl

Download URL ogc_edr_profile-2.0.0-py3-none-any.whl
Size 36.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
111f83dfe1959ba01a737d883caacfc2f21aa8ca20d24383e74be3dcc4f023fa
BLAKE2b-256 checksum
How to use checksums
6f35bbf6af055ffeed1edd03e9443889f3c8937d7fa47cbe637d3cf64d539823
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page