Python API

from pystac.extensions.themes import Theme, ThemeConcept, ThemesExtension
Entry point Behavior
ThemesExtension.ext(obj, add_if_missing=False) Wrap a Catalog, Collection, or Item.
ThemesExtension.summaries(collection, add_if_missing=False) Wrap Collection summaries.
extension.apply(themes) Replace the object's themes with a list of Theme values.
extension.themes Read, replace, or clear themes using None.
ThemesExtension.get_schema_uri() Return the Themes v1.0.0 schema URL.
ThemesExtension.has_extension(obj) Check for that URL in stac_extensions.
ThemesExtension.add_to(obj) Add the schema URL if absent.
ThemesExtension.remove_from(obj) Remove the schema declaration.
Theme.to_dict() / Theme.from_dict(data) Serialize or deserialize a theme.
ThemeConcept.to_dict() / ThemeConcept.from_dict(data) Serialize or deserialize a concept.

ext() and summaries() raise pystac.ExtensionNotImplemented when the declaration is missing unless add_if_missing=True. ext() raises pystac.ExtensionTypeError for unsupported objects.

Use ThemesExtension.ext(obj) directly. PySTAC does not provide item.ext.themes or catalog.ext.themes, and this package does not register those shortcuts. There is no from_item() alias.

pystac.extensions.themes

Implements the :stac-ext:Themes Extension <themes>.

SCHEMA_URI: str = 'https://stac-extensions.github.io/themes/v1.0.0/schema.json' module-attribute

THEMES_PROP: str = 'themes' module-attribute

THEMES_EXTENSION_HOOKS: ExtensionHooks = ThemesExtensionHooks() module-attribute

ThemeConcept

A concept in a knowledge organization system or controlled vocabulary.

Source code in pystac/extensions/themes.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class ThemeConcept:
    """A concept in a knowledge organization system or controlled vocabulary."""

    id: str
    title: str | None
    description: str | None
    url: str | None

    def __init__(
        self,
        id: str,
        title: str | None = None,
        description: str | None = None,
        url: str | None = None,
    ) -> None:
        self.id = id
        self.title = title
        self.description = description
        self.url = url

    def to_dict(self) -> dict[str, Any]:
        """Serialize this concept to its STAC representation."""
        result: dict[str, Any] = {"id": self.id}
        if self.title is not None:
            result["title"] = self.title
        if self.description is not None:
            result["description"] = self.description
        if self.url is not None:
            result["url"] = self.url
        return result

    @classmethod
    def from_dict(cls, d: dict[str, Any]) -> ThemeConcept:
        """Deserialize a concept from its STAC representation."""
        return cls(
            id=cast("str", d["id"]),
            title=cast("str | None", d.get("title")),
            description=cast("str | None", d.get("description")),
            url=cast("str | None", d.get("url")),
        )

    def __repr__(self) -> str:
        return f"<ThemeConcept id={self.id}>"

from_dict(d: dict[str, Any]) -> ThemeConcept classmethod

Deserialize a concept from its STAC representation.

Source code in pystac/extensions/themes.py
70
71
72
73
74
75
76
77
78
@classmethod
def from_dict(cls, d: dict[str, Any]) -> ThemeConcept:
    """Deserialize a concept from its STAC representation."""
    return cls(
        id=cast("str", d["id"]),
        title=cast("str | None", d.get("title")),
        description=cast("str | None", d.get("description")),
        url=cast("str | None", d.get("url")),
    )

to_dict() -> dict[str, Any]

Serialize this concept to its STAC representation.

Source code in pystac/extensions/themes.py
59
60
61
62
63
64
65
66
67
68
def to_dict(self) -> dict[str, Any]:
    """Serialize this concept to its STAC representation."""
    result: dict[str, Any] = {"id": self.id}
    if self.title is not None:
        result["title"] = self.title
    if self.description is not None:
        result["description"] = self.description
    if self.url is not None:
        result["url"] = self.url
    return result

Theme

A set of concepts from a knowledge organization system.

Source code in pystac/extensions/themes.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class Theme:
    """A set of concepts from a knowledge organization system."""

    scheme: str
    concepts: list[ThemeConcept]

    def __init__(self, scheme: str, concepts: list[ThemeConcept]) -> None:
        self.scheme = scheme
        self.concepts = concepts

    def to_dict(self) -> dict[str, Any]:
        """Serialize this theme to its STAC representation."""
        return {
            "scheme": self.scheme,
            "concepts": [concept.to_dict() for concept in self.concepts],
        }

    @classmethod
    def from_dict(cls, d: dict[str, Any]) -> Theme:
        """Deserialize a theme from its STAC representation."""
        return cls(
            scheme=cast("str", d["scheme"]),
            concepts=[
                ThemeConcept.from_dict(concept)
                for concept in cast("list[dict[str, Any]]", d["concepts"])
            ],
        )

    def __repr__(self) -> str:
        return f"<Theme scheme={self.scheme}>"

from_dict(d: dict[str, Any]) -> Theme classmethod

Deserialize a theme from its STAC representation.

Source code in pystac/extensions/themes.py
101
102
103
104
105
106
107
108
109
110
@classmethod
def from_dict(cls, d: dict[str, Any]) -> Theme:
    """Deserialize a theme from its STAC representation."""
    return cls(
        scheme=cast("str", d["scheme"]),
        concepts=[
            ThemeConcept.from_dict(concept)
            for concept in cast("list[dict[str, Any]]", d["concepts"])
        ],
    )

to_dict() -> dict[str, Any]

Serialize this theme to its STAC representation.

Source code in pystac/extensions/themes.py
94
95
96
97
98
99
def to_dict(self) -> dict[str, Any]:
    """Serialize this theme to its STAC representation."""
    return {
        "scheme": self.scheme,
        "concepts": [concept.to_dict() for concept in self.concepts],
    }

ThemesExtension

Bases: Generic[T], PropertiesExtension, ExtensionManagementMixin[Catalog | Collection | Item]

The Themes Extension for Catalogs, Collections, and Items.

Source code in pystac/extensions/themes.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
class ThemesExtension(
    Generic[T],
    PropertiesExtension,
    ExtensionManagementMixin[pystac.Catalog | pystac.Collection | pystac.Item],
):
    """The Themes Extension for Catalogs, Collections, and Items."""

    name: Literal["themes"] = "themes"

    def apply(self, themes: list[Theme]) -> None:
        """Apply Themes Extension fields to the extended STAC object."""
        self.themes = themes

    @property
    def themes(self) -> list[Theme] | None:
        """The themes for the extended object, or ``None`` when absent."""
        return map_opt(
            lambda themes: [Theme.from_dict(theme) for theme in themes],
            self._get_property(THEMES_PROP, list[dict[str, Any]]),
        )

    @themes.setter
    def themes(self, value: list[Theme] | None) -> None:
        self._set_property(
            THEMES_PROP,
            map_opt(lambda themes: [theme.to_dict() for theme in themes], value),
            pop_if_none=True,
        )

    @classmethod
    def get_schema_uri(cls) -> str:
        """Return the Themes v1.0.0 schema URI."""
        return SCHEMA_URI

    @classmethod
    def ext(cls, obj: T, add_if_missing: bool = False) -> ThemesExtension[T]:
        """Wrap a Catalog, Collection, or Item to access its themes.

        Args:
            obj: STAC object whose theme metadata will be read or updated.
            add_if_missing: Add the schema URI to the object's extension list.

        Raises:
            pystac.ExtensionNotImplemented: If the declaration is missing and
                ``add_if_missing`` is false.
            pystac.ExtensionTypeError: If the object type is unsupported.
        """
        if isinstance(obj, pystac.Collection):
            cls.ensure_has_extension(obj, add_if_missing)
            return cast("ThemesExtension[T]", CollectionThemesExtension(obj))
        if isinstance(obj, pystac.Catalog):
            cls.ensure_has_extension(obj, add_if_missing)
            return cast("ThemesExtension[T]", CatalogThemesExtension(obj))
        if isinstance(obj, pystac.Item):
            cls.ensure_has_extension(obj, add_if_missing)
            return cast("ThemesExtension[T]", ItemThemesExtension(obj))
        raise pystac.ExtensionTypeError(cls._ext_error_message(obj))

    @classmethod
    def summaries(
        cls, obj: pystac.Collection, add_if_missing: bool = False
    ) -> SummariesThemesExtension:
        """Return the Themes Extension wrapper for Collection summaries."""
        cls.ensure_has_extension(obj, add_if_missing)
        return SummariesThemesExtension(obj)

themes: list[Theme] | None property writable

The themes for the extended object, or None when absent.

apply(themes: list[Theme]) -> None

Apply Themes Extension fields to the extended STAC object.

Source code in pystac/extensions/themes.py
125
126
127
def apply(self, themes: list[Theme]) -> None:
    """Apply Themes Extension fields to the extended STAC object."""
    self.themes = themes

ext(obj: T, add_if_missing: bool = False) -> ThemesExtension[T] classmethod

Wrap a Catalog, Collection, or Item to access its themes.

Parameters:
  • obj (T) –

    STAC object whose theme metadata will be read or updated.

  • add_if_missing (bool, default: False ) –

    Add the schema URI to the object's extension list.

Raises:
  • ExtensionNotImplemented –

    If the declaration is missing and add_if_missing is false.

  • ExtensionTypeError –

    If the object type is unsupported.

Source code in pystac/extensions/themes.py
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
@classmethod
def ext(cls, obj: T, add_if_missing: bool = False) -> ThemesExtension[T]:
    """Wrap a Catalog, Collection, or Item to access its themes.

    Args:
        obj: STAC object whose theme metadata will be read or updated.
        add_if_missing: Add the schema URI to the object's extension list.

    Raises:
        pystac.ExtensionNotImplemented: If the declaration is missing and
            ``add_if_missing`` is false.
        pystac.ExtensionTypeError: If the object type is unsupported.
    """
    if isinstance(obj, pystac.Collection):
        cls.ensure_has_extension(obj, add_if_missing)
        return cast("ThemesExtension[T]", CollectionThemesExtension(obj))
    if isinstance(obj, pystac.Catalog):
        cls.ensure_has_extension(obj, add_if_missing)
        return cast("ThemesExtension[T]", CatalogThemesExtension(obj))
    if isinstance(obj, pystac.Item):
        cls.ensure_has_extension(obj, add_if_missing)
        return cast("ThemesExtension[T]", ItemThemesExtension(obj))
    raise pystac.ExtensionTypeError(cls._ext_error_message(obj))

get_schema_uri() -> str classmethod

Return the Themes v1.0.0 schema URI.

Source code in pystac/extensions/themes.py
145
146
147
148
@classmethod
def get_schema_uri(cls) -> str:
    """Return the Themes v1.0.0 schema URI."""
    return SCHEMA_URI

summaries(obj: pystac.Collection, add_if_missing: bool = False) -> SummariesThemesExtension classmethod

Return the Themes Extension wrapper for Collection summaries.

Source code in pystac/extensions/themes.py
174
175
176
177
178
179
180
@classmethod
def summaries(
    cls, obj: pystac.Collection, add_if_missing: bool = False
) -> SummariesThemesExtension:
    """Return the Themes Extension wrapper for Collection summaries."""
    cls.ensure_has_extension(obj, add_if_missing)
    return SummariesThemesExtension(obj)

CatalogThemesExtension

Bases: ThemesExtension[Catalog]

Read and write themes on a STAC Catalog.

Source code in pystac/extensions/themes.py
183
184
185
186
187
188
189
190
191
192
193
194
class CatalogThemesExtension(ThemesExtension[pystac.Catalog]):
    """Read and write themes on a STAC Catalog."""

    catalog: pystac.Catalog
    properties: dict[str, Any]

    def __init__(self, catalog: pystac.Catalog) -> None:
        self.catalog = catalog
        self.properties = catalog.extra_fields

    def __repr__(self) -> str:
        return f"<CatalogThemesExtension Catalog id={self.catalog.id}>"

CollectionThemesExtension

Bases: ThemesExtension[Collection]

Read and write themes on a STAC Collection.

Source code in pystac/extensions/themes.py
197
198
199
200
201
202
203
204
205
206
207
208
class CollectionThemesExtension(ThemesExtension[pystac.Collection]):
    """Read and write themes on a STAC Collection."""

    collection: pystac.Collection
    properties: dict[str, Any]

    def __init__(self, collection: pystac.Collection) -> None:
        self.collection = collection
        self.properties = collection.extra_fields

    def __repr__(self) -> str:
        return f"<CollectionThemesExtension Collection id={self.collection.id}>"

ItemThemesExtension

Bases: ThemesExtension[Item]

Read and write themes on a STAC Item.

Source code in pystac/extensions/themes.py
211
212
213
214
215
216
217
218
219
220
221
222
class ItemThemesExtension(ThemesExtension[pystac.Item]):
    """Read and write themes on a STAC Item."""

    item: pystac.Item
    properties: dict[str, Any]

    def __init__(self, item: pystac.Item) -> None:
        self.item = item
        self.properties = item.properties

    def __repr__(self) -> str:
        return f"<ItemThemesExtension Item id={self.item.id}>"

SummariesThemesExtension

Bases: SummariesExtension

The Themes Extension for Collection summaries.

Source code in pystac/extensions/themes.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
class SummariesThemesExtension(SummariesExtension):
    """The Themes Extension for Collection summaries."""

    @property
    def themes(self) -> list[Theme] | None:
        """The themes in Collection summaries, or ``None`` when absent."""
        return map_opt(
            lambda themes: [Theme.from_dict(theme) for theme in themes],
            self.summaries.get_list(THEMES_PROP),
        )

    @themes.setter
    def themes(self, value: list[Theme] | None) -> None:
        self._set_summary(
            THEMES_PROP,
            map_opt(lambda themes: [theme.to_dict() for theme in themes], value),
        )

themes: list[Theme] | None property writable

The themes in Collection summaries, or None when absent.

ThemesExtensionHooks

Bases: ExtensionHooks

Declare the schema and STAC object types supported by Themes.

Source code in pystac/extensions/themes.py
244
245
246
247
248
249
250
251
252
253
class ThemesExtensionHooks(ExtensionHooks):
    """Declare the schema and STAC object types supported by Themes."""

    schema_uri: str = SCHEMA_URI
    prev_extension_ids: ClassVar[set[str]] = set()
    stac_object_types: ClassVar[set[pystac.STACObjectType]] = {
        pystac.STACObjectType.CATALOG,
        pystac.STACObjectType.COLLECTION,
        pystac.STACObjectType.ITEM,
    }