Skip to content

BREAKING CHANGE: V2 STAC Extensions#1623

Closed
jsignell wants to merge 32 commits intov2from
v2-extensions
Closed

BREAKING CHANGE: V2 STAC Extensions#1623
jsignell wants to merge 32 commits intov2from
v2-extensions

Conversation

@jsignell
Copy link
Copy Markdown
Member

@jsignell jsignell commented Jan 6, 2026

Related Issue(s):

Description:

Lays out a vision for STAC Extension classes in pystac v2. The goal is to improve the user experience of working with pystac objects that include stac extension fields while making it dramatically easier to write and maintain the stac extension classes.

With this PR you would start with a pydantic model which can be autogenerated from the jsonschema and then tweaked a bit or written by hand. Then you just decorate the model with a special method called register_extension and add an import to extensions/__init__.py.

Once you have done those steps the user can access the fields (and there is type hinting) like:

from src import pystac


item = pystac.Item.from_file("tests/data-files/eo/eo-landsat-example.json")
item.ext.eo.cloud_cover

There are also some helper functions on item.ext.eo for instance to get the related extension url from stac_extensions:

item.ext.eo.get_url()

or to remove the given extension from stac_extensions:

item.ext.eo.remove()

To add a bunch of new extension fields the idea is that you would do something like:

from src.pystac.extensions import EOFields

blob = {
    "eo:bands": [
        {
          "name": "B1",
          "common_name": "coastal",
          "center_wavelength": 0.44,
          "full_width_half_max": 0.02,
          "solar_illumination": 2000
        }
    ]
}

f = EOFields(**blob)
item.ext.eo.apply(f)

Ongoing work:

  • Figure out typing on the register_extension mechanism
  • Is there a way to expand this so you can have different versions of extension and aren't forced to migrate?
  • How to exclude certain types of objects from using certain extensions?
  • Make it easier to unset a particular field.
  • Include removing all extension fields within the remove method?

PR Checklist:

  • Pre-commit hooks pass (run pre-commit run --all-files)
  • Tests pass (run pytest)
  • Documentation has been updated to reflect changes, if applicable
  • This PR maintains or improves overall codebase code coverage
  • This PR's title is formatted per conventional commits

@gadomski gadomski self-requested a review January 6, 2026 22:23
Copy link
Copy Markdown
Member

@gadomski gadomski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love (love love love) being able to auto-gen extensions from the JSON schema. This is a big enough win to justify lots of other pain, IMO.

I have a thought, not fully formed, that we could break extensions out of the pystac Python package entirely for v2. I'm thinking about namespace package plugins (probably in pystac.extensions): https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-namespace-packages. We could maintain "core" extensions in the pystac repo but in their own Python packages (e.g. pystac-projection or pystac-extension-projection). This would allow us to version the plugins separately (maybe even keep extension code versions matching their latest-supported jsonschema verision?). This would make it easier for folks to contribute extensions ... they could just publish their own Python package and it would be auto-detected by our plugin mechanism, if present.

@jsignell
Copy link
Copy Markdown
Member Author

jsignell commented Apr 3, 2026

Extensions are now separate from core pystac as of #1650

@jsignell jsignell closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants