diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c4558c4..c33f55e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,7 +25,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index bc10db7..7af07ae 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -19,45 +19,33 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - maturin: - - args: "-i 3.10" - name: python-310 - - args: "-i 3.11 -F pyo3/abi3-py311" - name: python-311+ platform: - target: x86_64 manylinux: auto - duckdb-slug: amd64 - target: aarch64 manylinux: "2_28" - duckdb-slug: aarch64 steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - name: Install Python - run: uv python install 3.10 + run: uv python install 3.11 - name: Build wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist ${{ matrix.maturin.args }} -F duckdb-bundled + args: --release --out dist -i 3.11 -F pyo3/abi3-py311 -F duckdb-bundled sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: ${{ matrix.platform.manylinux }} - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-linux-${{ matrix.platform.target }}-${{ matrix.maturin.name }} + name: wheels-linux-${{ matrix.platform.target }} path: dist macos: runs-on: ${{ matrix.platform.runner }} strategy: matrix: - maturin: - - args: "-i 3.10" - name: python-310 - - args: "-i 3.11 -F pyo3/abi3-py311" - name: python-311+ platform: - runner: macos-13 target: x86_64 @@ -67,17 +55,17 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - name: Install Python - run: uv python install 3.10 + run: uv python install 3.11 - name: Build wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist ${{ matrix.maturin.args }} -F duckdb-bundled + args: --release --out dist -i 3.11 -F pyo3/abi3-py311 -F duckdb-bundled sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-macos-${{ matrix.platform.target }}-${{ matrix.maturin.name }} + name: wheels-macos-${{ matrix.platform.target }} path: dist sdist: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7387813..045f6c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Deterministic asset ordering ([rustac #709](https://github.com/stac-utils/rustac/pull/709), [#93](https://github.com/stac-utils/rustac-py/pull/93)) - Normalize search output ([#102](https://github.com/stac-utils/rustac-py/pull/102)) +### Removed + +- Python 3.10 support ([#110](https://github.com/stac-utils/rustac-py/pull/110)) + ## [0.6.0] - 2025-04-18 > [!NOTE] diff --git a/pyproject.toml b/pyproject.toml index 2b39c92..0959b9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,14 +3,13 @@ name = "rustac" description = "The power of Rust for the Python STAC ecosystem" readme = "README.md" authors = [{ name = "Pete Gadomski", email = "pete.gadomski@gmail.com" }] -requires-python = ">=3.10" +requires-python = ">=3.11" classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "License :: OSI Approved :: MIT License", "Natural Language :: English", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", diff --git a/python/rustac/__init__.py b/python/rustac/__init__.py index 4bb3ffc..da5e16d 100644 --- a/python/rustac/__init__.py +++ b/python/rustac/__init__.py @@ -1,54 +1,54 @@ from __future__ import annotations from .rustac import * -from typing import TypedDict +from typing import TypedDict, Required, Any, Literal -class Catalog(TypedDict): +class Catalog(TypedDict, total=False): """A STAC Catalog object represents a logical group of other Catalog, Collection, and Item objects.""" - type: str + type: Required[str] """Set to Catalog if this Catalog only implements the Catalog spec.""" - stac_version: str + stac_version: Required[str] """The STAC version the Catalog implements.""" stac_extensions: list[str] | None """A list of extension identifiers the Catalog implements.""" - id: str + id: Required[str] """Identifier for the Catalog.""" title: str | None """A short descriptive one-line title for the Catalog.""" - description: str + description: Required[str] """Detailed multi-line description to fully explain the Catalog. CommonMark 0.29 syntax MAY be used for rich text representation.""" - links: list[Link] + links: Required[list[Link]] """A list of references to other documents.""" -class Collection(TypedDict): +class Collection(TypedDict, total=False): """The STAC Collection Specification defines a set of common fields to describe a group of Items that share properties and metadata.""" - type: str + type: Required[str] """Must be set to Collection to be a valid Collection.""" - stac_version: str + stac_version: Required[str] """The STAC version the Collection implements.""" stac_extensions: list[str] | None """A list of extension identifiers the Collection implements.""" - id: str + id: Required[str] """Identifier for the Collection that is unique across all collections in the root catalog.""" title: str | None """A short descriptive one-line title for the Collection.""" - description: str + description: Required[str] """Detailed multi-line description to fully explain the Collection. CommonMark 0.29 syntax MAY be used for rich text representation.""" @@ -56,19 +56,19 @@ class Collection(TypedDict): keywords: list[str] | None """List of keywords describing the Collection.""" - license: str + license: Required[str] """License(s) of the data collection as SPDX License identifier, SPDX License expression, or `other`.""" providers: list[Provider] | None """A list of providers, which may include all organizations capturing or processing the data or the hosting provider.""" - extent: Extent + extent: Required[Extent] """Spatial and temporal extents.""" - summaries: dict[str, Any] + summaries: dict[str, Any] | None """A map of property summaries, either a set of values, a range of values or a JSON Schema.""" - links: list[Link] + links: Required[list[Link]] """A list of references to other documents.""" assets: dict[str, Asset] | None @@ -77,10 +77,10 @@ class Collection(TypedDict): item_assets: dict[str, ItemAsset] | None """A dictionary of assets that can be found in member Items.""" -class Provider(TypedDict): +class Provider(TypedDict, total=False): """A provider is any of the organizations that captures or processes the content of the Collection and therefore influences the data offered by this Collection.""" - name: str + name: Required[str] """The name of the organization or the individual.""" description: str | None @@ -93,7 +93,7 @@ class Provider(TypedDict): | Literal["producer"] | Literal["processor"] | Literal["host"] - ] + ] | None """Roles of the provider.""" url: str | None @@ -120,7 +120,7 @@ class TemporalExtent(TypedDict): bbox: list[list[str | None]] """Potential temporal extents covered by the Collection.""" -class ItemAsset(TypedDict): +class ItemAsset(TypedDict, total=False): """An Item Asset Object defined at the Collection level is nearly the same as the Asset Object in Items, except for two differences. The href field is not required, because Item Asset Definitions don't point to any data by themselves, but at least two other fields must be present.""" @@ -139,19 +139,19 @@ class ItemAsset(TypedDict): roles: list[str] | None """The semantic roles of the asset, similar to the use of rel in links.""" -class Item(TypedDict): +class Item(TypedDict, total=False): """An Item is a GeoJSON Feature augmented with foreign members relevant to a STAC object.""" - type: str + type: Required[str] """Type of the GeoJSON Object. MUST be set to Feature.""" - stac_version: str + stac_version: Required[str] """The STAC version the Item implements.""" stac_extensions: list[str] | None """A list of extensions the Item implements.""" - id: str + id: Required[str] """Provider identifier. The ID should be unique within the Collection that contains the Item.""" geometry: dict[str, Any] | None @@ -162,15 +162,15 @@ class Item(TypedDict): Bounding Box of the asset represented by this Item, formatted according to RFC 7946, section 5.""" - properties: Properties + properties: Required[Properties] """A dictionary of additional metadata for the Item.""" - links: list[Link] + links: Required[list[Link]] """List of link objects to resources and related URLs. See the best practices for details on when the use self links is strongly recommended.""" - assets: dict[str, Asset] + assets: Required[dict[str, Asset]] """Dictionary of asset objects that can be downloaded, each with a unique key.""" collection: str | None @@ -186,19 +186,19 @@ class Properties(TypedDict): It is formatted according to RFC 3339, section 5.6. null is allowed, but requires start_datetime and end_datetime from common metadata to be set.""" -class Link(TypedDict): +class Link(TypedDict, total=False): """This object describes a relationship with another entity. Data providers are advised to be liberal with the links section, to describe things like the Catalog an Item is in, related Items, parent or child Items (modeled in different ways, like an 'acquisition' or derived data).""" - href: str + href: Required[str] """The actual link in the format of an URL. Relative and absolute links are both allowed. Trailing slashes are significant.""" - rel: str + rel: Required[str] """Relationship between the current document and the linked document.""" type: str | None @@ -218,12 +218,12 @@ class Link(TypedDict): body: Any | None """The HTTP body to be sent to the target resource.""" -class Asset(TypedDict): +class Asset(TypedDict, total=False): """An Asset is an object that contains a URI to data associated with the Item that can be downloaded or streamed. It is allowed to add additional fields.""" - href: str + href: Required[str] """URI to the asset object. Relative and absolute URI are both allowed. Trailing slashes are significant.""" title: str | None