Generate your first extension¶
Install the CLI, then work in an empty directory. This example defines a small quality-metadata extension for Items and their Assets.
1. Save the extension schema¶
Save the following as quality-schema.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/quality/v1.0.0/schema.json",
"title": "Quality Extension",
"type": "object",
"required": ["type", "stac_extensions", "properties"],
"properties": {
"type": {"const": "Feature"},
"stac_extensions": {
"type": "array",
"contains": {"const": "https://example.org/quality/v1.0.0/schema.json"}
},
"properties": {"$ref": "#/$defs/fields"},
"assets": {
"type": "object",
"additionalProperties": {"$ref": "#/$defs/fields"}
}
},
"$defs": {
"fields": {
"type": "object",
"properties": {
"quality:score": {
"description": "Quality score between zero and one.",
"type": "number",
"minimum": 0,
"maximum": 1
},
"quality:details": {"$ref": "#/$defs/quality_details"}
}
},
"quality_details": {
"type": "object",
"required": ["method"],
"properties": {
"method": {"type": "string"},
"samples": {"type": "integer", "minimum": 1}
}
}
}
}
The example.org identifier is illustrative. This tutorial validates against the
schema embedded in the generated module, so that URL does not need to resolve.
Use a published canonical schema URL for an extension you distribute.
2. Generate the Python module¶
pystac-ext-generator quality-schema.json --include-validation -o quality_extension.py
This tutorial opts into embedded validation so its illustrative schema can be
validated offline. Without --include-validation, use PySTAC
item.validate() and a published or locally configured schema resolver.
The title produces QualityExtension, and the referenced object definition
produces QualityDetails. The references under Item properties and assets
establish applicability automatically. Existing output files are protected;
pass --force when regenerating intentionally.
3. Use the generated classes¶
Save this as use_quality.py next to the generated module:
import json
from datetime import datetime, timezone
import pystac
from quality_extension import QualityDetails, QualityExtension
item = pystac.Item(
id="quality-example",
geometry=None,
bbox=None,
datetime=datetime(2026, 1, 1, tzinfo=timezone.utc),
properties={},
)
extension = QualityExtension.ext(item, add_if_missing=True)
extension.apply(
score=0.9,
details=QualityDetails.create(method="manual", samples=12),
)
extension.validate()
serialized = json.loads(json.dumps(item.to_dict()))
assert serialized["properties"]["quality:score"] == 0.9
assert QualityExtension.get_schema_uri() in serialized["stac_extensions"]
restored_item = pystac.Item.from_dict(serialized)
restored = QualityExtension.ext(restored_item)
assert restored.details.method == "manual"
assert restored.details.samples == 12
restored.validate()
Run it:
python use_quality.py
add_if_missing=True registers the schema URI on the Item. Nested value classes
serialize as ordinary JSON objects. validate() checks the whole Item against
the embedded extension schema; to_dict() alone does not validate values.
Continue with updates, asset inheritance, and nested values.