diff --git a/.github/workflows/maturin.yml b/.github/workflows/maturin.yml new file mode 100644 index 00000000..23169950 --- /dev/null +++ b/.github/workflows/maturin.yml @@ -0,0 +1,158 @@ +# This file is autogenerated by maturin v1.3.0 +# To update, run +# +# maturin generate-ci github -m pystac/Cargo.toml --pytest +# +name: Maturin + +on: + push: + branches: + - main + tags: + - '*' + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + linux: + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter --manifest-path pystac/Cargo.toml + sccache: 'true' + manylinux: auto + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + - name: pytest + if: ${{ startsWith(matrix.target, 'x86_64') }} + shell: bash + run: | + set -e + pip install pystac-rs --find-links dist --force-reinstall + pip install pytest + cd pystac && pytest + - name: pytest + if: ${{ !startsWith(matrix.target, 'x86') && matrix.target != 'ppc64' }} + uses: uraimo/run-on-arch-action@v2.5.0 + with: + arch: ${{ matrix.target }} + distro: ubuntu22.04 + githubToken: ${{ github.token }} + install: | + apt-get update + apt-get install -y --no-install-recommends python3 python3-pip + pip3 install -U pip pytest + run: | + set -e + pip3 install pystac-rs --find-links dist --force-reinstall + cd pystac && pytest + + windows: + runs-on: windows-latest + strategy: + matrix: + target: [x64, x86] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + architecture: ${{ matrix.target }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter --manifest-path pystac/Cargo.toml + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + - name: pytest + if: ${{ !startsWith(matrix.target, 'aarch64') }} + shell: bash + run: | + set -e + pip install pystac-rs --find-links dist --force-reinstall + pip install pytest + cd pystac && pytest + + macos: + runs-on: macos-latest + strategy: + matrix: + target: [x86_64, aarch64] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter --manifest-path pystac/Cargo.toml + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + - name: pytest + if: ${{ !startsWith(matrix.target, 'aarch64') }} + shell: bash + run: | + set -e + pip install pystac-rs --find-links dist --force-reinstall + pip install pytest + cd pystac && pytest + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist --manifest-path pystac/Cargo.toml + - name: Upload sdist + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + release: + name: Release + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + needs: [linux, windows, macos, sdist] + steps: + - uses: actions/download-artifact@v3 + with: + name: wheels + - name: Publish to PyPI + uses: PyO3/maturin-action@v1 + env: + MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + with: + command: upload + args: --non-interactive --skip-existing * diff --git a/Cargo.toml b/Cargo.toml index 29da4d0e..c81f366d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "pystac", "stac", "stac-api", "stac-async", diff --git a/pystac/.gitignore b/pystac/.gitignore new file mode 100644 index 00000000..af3ca5ef --- /dev/null +++ b/pystac/.gitignore @@ -0,0 +1,72 @@ +/target + +# Byte-compiled / optimized / DLL files +__pycache__/ +.pytest_cache/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +.venv/ +env/ +bin/ +build/ +develop-eggs/ +dist/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +include/ +man/ +venv/ +*.egg-info/ +.installed.cfg +*.egg + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt +pip-selfcheck.json + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Rope +.ropeproject + +# Django stuff: +*.log +*.pot + +.DS_Store + +# Sphinx documentation +docs/_build/ + +# PyCharm +.idea/ + +# VSCode +.vscode/ + +# Pyenv +.python-version \ No newline at end of file diff --git a/pystac/Cargo.toml b/pystac/Cargo.toml new file mode 100644 index 00000000..ec1294fc --- /dev/null +++ b/pystac/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "pystac" +version = "0.0.1" +edition = "2021" + +[lib] +name = "pystac_rs" +crate-type = ["cdylib"] + +[dependencies] +pyo3 = "0.20.0" +stac = { version = "0.5", path = "../stac" } diff --git a/pystac/pyproject.toml b/pystac/pyproject.toml new file mode 100644 index 00000000..e87a8bde --- /dev/null +++ b/pystac/pyproject.toml @@ -0,0 +1,19 @@ +[project] +name = "pystac-rs" +requires-python = ">=3.9" +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = ["pytest~=7.4"] + +[tool.maturin] +features = ["pyo3/extension-module"] + +[build-system] +requires = ["maturin>=1.3,<2.0"] +build-backend = "maturin" diff --git a/pystac/pystac_rs.pyi b/pystac/pystac_rs.pyi new file mode 100644 index 00000000..890e50d2 --- /dev/null +++ b/pystac/pystac_rs.pyi @@ -0,0 +1,2 @@ +class Item: + id: str diff --git a/pystac/src/item.rs b/pystac/src/item.rs new file mode 100644 index 00000000..6d0e2a0c --- /dev/null +++ b/pystac/src/item.rs @@ -0,0 +1,22 @@ +use pyo3::prelude::*; + +#[pyclass] +pub struct Item(stac::Item); + +#[pymethods] +impl Item { + #[new] + fn new(id: String) -> Item { + Item(stac::Item::new(id)) + } + + #[getter] + fn id(&self) -> &str { + &self.0.id + } + + #[setter] + fn set_id(&mut self, id: String) { + self.0.id = id; + } +} diff --git a/pystac/src/lib.rs b/pystac/src/lib.rs new file mode 100644 index 00000000..c473b7e8 --- /dev/null +++ b/pystac/src/lib.rs @@ -0,0 +1,4 @@ +mod item; +mod module; + +pub use item::Item; diff --git a/pystac/src/module.rs b/pystac/src/module.rs new file mode 100644 index 00000000..dd99b4db --- /dev/null +++ b/pystac/src/module.rs @@ -0,0 +1,10 @@ +use crate::Item; +use pyo3::prelude::*; + +/// pystac-rs is a library for working with the SpatioTemporal Asset Catalog +/// (STAC) specification, written in Rust. +#[pymodule] +fn pystac_rs(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + Ok(()) +} diff --git a/pystac/tests/test_item.py b/pystac/tests/test_item.py new file mode 100644 index 00000000..4f064e0d --- /dev/null +++ b/pystac/tests/test_item.py @@ -0,0 +1,8 @@ +from pystac_rs import Item + + +def test_init(): + item = Item("an-id") + assert item.id == "an-id" + item.id = "new-id" + assert item.id == "new-id"