# stac-model
<!--lint disable no-html -->
<div align="center">
[![Python support][bp1]][bp2]
[![PyPI Release][bp3]][bp2]
[![Repository][bscm1]][bp4]
[![Releases][bscm2]][bp5]
[![Contributions Welcome][bp8]][bp9]
[![uv][bp11]][bp12]
[![Pre-commit][bp15]][bp16]
[![Semantic versions][blic3]][bp5]
[![Pipelines][bscm6]][bscm7]
*A PydanticV2 and PySTAC validation and serialization library for the STAC ML Model Extension*
</div>
> ⚠️ <br>
> FIXME: update description with ML framework connectors (pytorch, scikit-learn, etc.)
## Installation
```shell
pip install -U stac-model
```
or install with uv:
```shell
uv add stac-model
```
Then you can run
```shell
stac-model --help
```
## Creating example metadata JSON for a STAC Item
```shell
stac-model
```
This will make [this example item](./examples/item_basic.json) for an example model.
## Validating Model Metadata
An alternative use of `stac_model` is to validate config files containing model metadata using the `MLModelProperties` schema.
Given a YAML or JSON file with the structure in [examples/torch/mlm-metadata.yaml](./examples/torch/mlm-metadata.yaml), the model metadata can be validated as follows:
```python
import yaml
from stac_model.schema import MLModelProperties
with open("examples/mlm-metadata.yaml", "r", encoding="utf-8") as f:
metadata = yaml.safe_load(f)
MLModelProperties.model_validate(metadata["properties"])
```
## Exporting and Packaging PyTorch Models, Transforms, and Model Metadata
As of PyTorch 2.8, and stac_model 0.4.0, you can now export and package PyTorch models, transforms,
and model metadata using functions in `stac_model.torch.export`. Below is an example of exporting a
U-Net model pretrained on the [Fields of The World (FTW) dataset](https://fieldsofthe.world/) for
field boundary segmentation in Sentinel-2 satellite imagery using the [TorchGeo](https://github.com/microsoft/torchgeo) library.
> 📝 **Note:** To customize the metadata for your model you can use this [example](./tests/torch/metadata.yaml) as a template.
```python
import torch
import torchvision.transforms.v2 as T
from torchgeo.models import Unet_Weights, unet
from stac_model.torch.export import save
weights = Unet_Weights.SENTINEL2_3CLASS_FTW
transforms = torch.nn.Sequential(
T.Resize((256, 256)),
T.Normalize(mean=[0.0], std=[3000.0])
)
model = unet(weights=weights)
save(
output_file="ftw.pt2",
model=model, # Must be an nn.Module
transforms=transforms, # Must be an nn.Module
metadata_path="metadata.yaml", # Can be a metadata yaml or stac_model.schema.MLModelProperties object
input_shape=[-1, 8, -1, -1], # -1 indicates a dynamic shaped dimension
device="cpu",
dtype=torch.float32,
aoti_compile_and_package=False, # True for AOTInductor compile otherwise use torch.export
)
```
The model, transforms, and metadata can then be loaded into an environment with only torch and stac_model as required dependencies like below:
```python
import yaml
from torch.export.pt2_archive._package import load_pt2
pt2 = load_pt2(archive_path)
metadata = yaml.safe_load(pt2.extra_files["mlm-metadata"])
# If exported with aoti_compile_and_package=True
model = pt2.aoti_runners["model"]
transforms = pt2.aoti_runners["transforms"]
# If exported with aoti_compile_and_package=False
model = pt2.exported_programs["model"].module()
transforms = pt2.exported_programs["transforms"].module()
# Inference
batch = ... # An input batch tensor
outputs = model(transforms(batch))
```
### Creating a STAC Item from a PyTorch Model
You can generate a valid STAC Item using the **Machine Learning Model (MLM) Extension**.
The example below demonstrates creating a STAC Item from a U-Net model pretrained on the
[Fields of The World (FTW) dataset](https://fieldsofthe.world/) for field boundary segmentation
in Sentinel-2 satellite imagery, using the [TorchGeo](https://github.com/microsoft/torchgeo) library
```python
from stac_model.examples import unet_mlm
from stac_model.torch import MLModelExtension
from torchgeo.models import unet, Unet_Weights
# Use default TorchGeo UNet weights
weights = Unet_Weights.SENTINEL2_2CLASS_NC_FTW
model = unet(weights=weights)
# Create an ItemMLModelExtension using the MLM extension
item_ext = MLModelExtension.from_torch(
model,
weights=weights,
item_id="pytorch_geo_unet"
)
```
For a more complete example including STAC Item properties, geometry, and datetime ranges,
see `unet_mlm()` in [`stac_model/examples.py`](stac_model/examples.py).
## 📈 Releases
You can see the list of available releases on the [GitHub Releases][github-releases] page.
## 📄 License
[![License][blic1]][blic2]
This project is licenced under the terms of the `Apache Software License 2.0` licence.
See [LICENSE][blic2] for more details.
## 💗 Credits
[![Python project templated from galactipy.][bp6]][bp7]
<!-- Anchors -->
[bp1]: https://img.shields.io/pypi/pyversions/stac-model?style=for-the-badge
[bp2]: https://pypi.org/project/stac-model/
[bp3]: https://img.shields.io/pypi/v/stac-model?style=for-the-badge&logo=pypi&color=3775a9
[bp4]: https://github.com/stac-extensions/mlm
[bp5]: https://github.com/stac-extensions/mlm/releases
[bp6]: https://img.shields.io/badge/made%20with-galactipy%20%F0%9F%8C%8C-179287?style=for-the-badge&labelColor=193A3E
[bp7]: https://kutt.it/7fYqQl
[bp8]: https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=for-the-badge
[bp9]: https://github.com/stac-extensions/mlm/blob/main/CONTRIBUTING.md
[bp11]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=for-the-badge
[bp12]: https://docs.astral.sh/uv/
[bp15]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge
[bp16]: https://github.com/stac-extensions/mlm/blob/main/.pre-commit-config.yaml
[blic1]: https://img.shields.io/github/license/stac-extensions/mlm?style=for-the-badge
[blic2]: https://github.com/stac-extensions/mlm/blob/main/LICENSE
[blic3]: https://img.shields.io/badge/%F0%9F%93%A6-semantic%20versions-4053D6?style=for-the-badge
[github-releases]: https://github.com/stac-extensions/mlm/releases
[bscm1]: https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white
[bscm2]: https://img.shields.io/github/v/release/stac-extensions/mlm?filter=stac-model-v*&style=for-the-badge&logo=semantic-release&color=347d39
[bscm6]: https://img.shields.io/github/actions/workflow/status/stac-extensions/mlm/publish.yaml?style=for-the-badge&logo=github
[bscm7]: https://github.com/stac-extensions/mlm/blob/main/.github/workflows/publish.yaml
[hub1]: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates#enabling-dependabot-version-updates
[hub2]: https://github.com/marketplace/actions/close-stale-issues
[hub6]: https://docs.github.com/en/code-security/dependabot
[hub8]: https://github.com/stac-extensions/mlm/blob/main/.github/release-drafter.yml
[hub9]: https://github.com/stac-extensions/mlm/blob/main/.github/.stale.yml
Raw data
{
"_id": null,
"home_page": null,
"name": "stac-model",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "STAC, SpatioTemporal Asset Catalog, Machine Learning Model, Artificial Intelligence",
"author": null,
"author_email": "Ryan Avery <ryan@wherobots.com>, Francis Charette-Migneault <francis.charette-migneault@crim.ca>",
"download_url": "https://files.pythonhosted.org/packages/1b/70/97ac6013e2840889d2b89b1f41e81ff8a1d3002dc6207c67e91d3a646aa8/stac_model-0.4.0.tar.gz",
"platform": null,
"description": "# stac-model\n\n<!--lint disable no-html -->\n\n<div align=\"center\">\n\n[![Python support][bp1]][bp2]\n[![PyPI Release][bp3]][bp2]\n[![Repository][bscm1]][bp4]\n[![Releases][bscm2]][bp5]\n\n[![Contributions Welcome][bp8]][bp9]\n\n[![uv][bp11]][bp12]\n[![Pre-commit][bp15]][bp16]\n[![Semantic versions][blic3]][bp5]\n[![Pipelines][bscm6]][bscm7]\n\n*A PydanticV2 and PySTAC validation and serialization library for the STAC ML Model Extension*\n\n</div>\n\n> \u26a0\ufe0f <br>\n> FIXME: update description with ML framework connectors (pytorch, scikit-learn, etc.)\n\n## Installation\n\n```shell\npip install -U stac-model\n```\n\nor install with uv:\n\n```shell\nuv add stac-model\n```\n\nThen you can run\n\n```shell\nstac-model --help\n```\n\n## Creating example metadata JSON for a STAC Item\n\n```shell\nstac-model\n```\n\nThis will make [this example item](./examples/item_basic.json) for an example model.\n\n## Validating Model Metadata\n\nAn alternative use of `stac_model` is to validate config files containing model metadata using the `MLModelProperties` schema.\n\nGiven a YAML or JSON file with the structure in [examples/torch/mlm-metadata.yaml](./examples/torch/mlm-metadata.yaml), the model metadata can be validated as follows:\n\n```python\nimport yaml\nfrom stac_model.schema import MLModelProperties\n\nwith open(\"examples/mlm-metadata.yaml\", \"r\", encoding=\"utf-8\") as f:\n metadata = yaml.safe_load(f)\n\nMLModelProperties.model_validate(metadata[\"properties\"]) \n```\n\n## Exporting and Packaging PyTorch Models, Transforms, and Model Metadata\n\nAs of PyTorch 2.8, and stac_model 0.4.0, you can now export and package PyTorch models, transforms,\nand model metadata using functions in `stac_model.torch.export`. Below is an example of exporting a\nU-Net model pretrained on the [Fields of The World (FTW) dataset](https://fieldsofthe.world/) for\nfield boundary segmentation in Sentinel-2 satellite imagery using the [TorchGeo](https://github.com/microsoft/torchgeo) library.\n\n> \ud83d\udcdd **Note:** To customize the metadata for your model you can use this [example](./tests/torch/metadata.yaml) as a template.\n\n```python\nimport torch\nimport torchvision.transforms.v2 as T\nfrom torchgeo.models import Unet_Weights, unet\nfrom stac_model.torch.export import save\n\nweights = Unet_Weights.SENTINEL2_3CLASS_FTW\ntransforms = torch.nn.Sequential(\n T.Resize((256, 256)),\n T.Normalize(mean=[0.0], std=[3000.0])\n)\nmodel = unet(weights=weights)\n\nsave(\n output_file=\"ftw.pt2\",\n model=model, # Must be an nn.Module\n transforms=transforms, # Must be an nn.Module\n metadata_path=\"metadata.yaml\", # Can be a metadata yaml or stac_model.schema.MLModelProperties object\n input_shape=[-1, 8, -1, -1], # -1 indicates a dynamic shaped dimension\n device=\"cpu\",\n dtype=torch.float32,\n aoti_compile_and_package=False, # True for AOTInductor compile otherwise use torch.export\n)\n```\n\nThe model, transforms, and metadata can then be loaded into an environment with only torch and stac_model as required dependencies like below:\n\n```python\nimport yaml\nfrom torch.export.pt2_archive._package import load_pt2\n\npt2 = load_pt2(archive_path)\nmetadata = yaml.safe_load(pt2.extra_files[\"mlm-metadata\"])\n\n# If exported with aoti_compile_and_package=True\nmodel = pt2.aoti_runners[\"model\"]\ntransforms = pt2.aoti_runners[\"transforms\"]\n\n# If exported with aoti_compile_and_package=False\nmodel = pt2.exported_programs[\"model\"].module()\ntransforms = pt2.exported_programs[\"transforms\"].module()\n\n# Inference\nbatch = ... # An input batch tensor\noutputs = model(transforms(batch))\n```\n\n### Creating a STAC Item from a PyTorch Model\n\nYou can generate a valid STAC Item using the **Machine Learning Model (MLM) Extension**. \n\nThe example below demonstrates creating a STAC Item from a U-Net model pretrained on the \n[Fields of The World (FTW) dataset](https://fieldsofthe.world/) for field boundary segmentation \nin Sentinel-2 satellite imagery, using the [TorchGeo](https://github.com/microsoft/torchgeo) library\n\n```python\nfrom stac_model.examples import unet_mlm\nfrom stac_model.torch import MLModelExtension\nfrom torchgeo.models import unet, Unet_Weights\n\n# Use default TorchGeo UNet weights\nweights = Unet_Weights.SENTINEL2_2CLASS_NC_FTW\nmodel = unet(weights=weights)\n\n# Create an ItemMLModelExtension using the MLM extension\nitem_ext = MLModelExtension.from_torch(\n model,\n weights=weights,\n item_id=\"pytorch_geo_unet\"\n)\n\n```\n\nFor a more complete example including STAC Item properties, geometry, and datetime ranges,\nsee `unet_mlm()` in [`stac_model/examples.py`](stac_model/examples.py).\n\n## \ud83d\udcc8 Releases\n\nYou can see the list of available releases on the [GitHub Releases][github-releases] page.\n\n## \ud83d\udcc4 License\n\n[![License][blic1]][blic2]\n\nThis project is licenced under the terms of the `Apache Software License 2.0` licence.\nSee [LICENSE][blic2] for more details.\n\n## \ud83d\udc97 Credits\n\n[![Python project templated from galactipy.][bp6]][bp7]\n\n<!-- Anchors -->\n\n[bp1]: https://img.shields.io/pypi/pyversions/stac-model?style=for-the-badge\n\n[bp2]: https://pypi.org/project/stac-model/\n\n[bp3]: https://img.shields.io/pypi/v/stac-model?style=for-the-badge&logo=pypi&color=3775a9\n\n[bp4]: https://github.com/stac-extensions/mlm\n\n[bp5]: https://github.com/stac-extensions/mlm/releases\n\n[bp6]: https://img.shields.io/badge/made%20with-galactipy%20%F0%9F%8C%8C-179287?style=for-the-badge&labelColor=193A3E\n\n[bp7]: https://kutt.it/7fYqQl\n\n[bp8]: https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=for-the-badge\n\n[bp9]: https://github.com/stac-extensions/mlm/blob/main/CONTRIBUTING.md\n\n[bp11]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=for-the-badge\n\n[bp12]: https://docs.astral.sh/uv/\n\n[bp15]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge\n\n[bp16]: https://github.com/stac-extensions/mlm/blob/main/.pre-commit-config.yaml\n\n[blic1]: https://img.shields.io/github/license/stac-extensions/mlm?style=for-the-badge\n\n[blic2]: https://github.com/stac-extensions/mlm/blob/main/LICENSE\n\n[blic3]: https://img.shields.io/badge/%F0%9F%93%A6-semantic%20versions-4053D6?style=for-the-badge\n\n[github-releases]: https://github.com/stac-extensions/mlm/releases\n\n[bscm1]: https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white\n\n[bscm2]: https://img.shields.io/github/v/release/stac-extensions/mlm?filter=stac-model-v*&style=for-the-badge&logo=semantic-release&color=347d39\n\n[bscm6]: https://img.shields.io/github/actions/workflow/status/stac-extensions/mlm/publish.yaml?style=for-the-badge&logo=github\n\n[bscm7]: https://github.com/stac-extensions/mlm/blob/main/.github/workflows/publish.yaml\n\n[hub1]: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates#enabling-dependabot-version-updates\n\n[hub2]: https://github.com/marketplace/actions/close-stale-issues\n\n[hub6]: https://docs.github.com/en/code-security/dependabot\n\n[hub8]: https://github.com/stac-extensions/mlm/blob/main/.github/release-drafter.yml\n\n[hub9]: https://github.com/stac-extensions/mlm/blob/main/.github/.stale.yml\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "A PydanticV2 validation and serialization libary for the STAC ML Model Extension",
"version": "0.4.0",
"project_urls": {
"homepage": "https://github.com/stac-extensions/mlm/blob/main/README_STAC_MODEL.md",
"repository": "https://github.com/crim-ca/mlm-extension"
},
"split_keywords": [
"stac",
" spatiotemporal asset catalog",
" machine learning model",
" artificial intelligence"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ce872a7646ba967ad2a1c34dd1f4584deba2b8f55abc2ed15acc9f6005fae55d",
"md5": "17d7d894eb8f487bc2f1931e264a0156",
"sha256": "e0ad3b79099cef8c74368d64e12f5e132a7f0b62efdfb1dca166d7490c4485ac"
},
"downloads": -1,
"filename": "stac_model-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "17d7d894eb8f487bc2f1931e264a0156",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 29965,
"upload_time": "2025-08-23T02:03:05",
"upload_time_iso_8601": "2025-08-23T02:03:05.183426Z",
"url": "https://files.pythonhosted.org/packages/ce/87/2a7646ba967ad2a1c34dd1f4584deba2b8f55abc2ed15acc9f6005fae55d/stac_model-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1b7097ac6013e2840889d2b89b1f41e81ff8a1d3002dc6207c67e91d3a646aa8",
"md5": "59510e742b56cd49b0d2b580ab29aee0",
"sha256": "739be739c75abeba5916b3cd6c88d10204039e7ebed775a10cd59b10f6ad378e"
},
"downloads": -1,
"filename": "stac_model-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "59510e742b56cd49b0d2b580ab29aee0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 36709,
"upload_time": "2025-08-23T02:03:06",
"upload_time_iso_8601": "2025-08-23T02:03:06.326304Z",
"url": "https://files.pythonhosted.org/packages/1b/70/97ac6013e2840889d2b89b1f41e81ff8a1d3002dc6207c67e91d3a646aa8/stac_model-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-23 02:03:06",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stac-extensions",
"github_project": "mlm",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "stac-model"
}