diff --git a/.github/.backend_git_ref b/.github/.backend_git_ref index 88d050b..4ef918d 100644 --- a/.github/.backend_git_ref +++ b/.github/.backend_git_ref @@ -1 +1 @@ -main \ No newline at end of file +c4af2b856f9205ce9848d5b9695cf4710c25e83f \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56cbc0b..77a8926 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,23 +3,16 @@ name: CI on: pull_request: merge_group: + # Creates a coverage of the main branch + push: + branches: + - main # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: check: - runs-on: ubuntu-22.04 - - services: - postgres: - image: postgis/postgis - env: - POSTGRES_USER: geoengine - POSTGRES_PASSWORD: geoengine - POSTGRES_DB: geoengine - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + uses: geo-engine/geoengine-python/.github/workflows/test-python.yml@reusable-workflow strategy: fail-fast: false @@ -27,189 +20,17 @@ jobs: # use all supported versions from https://devguide.python.org/versions/ python-version: ["3.9", "3.10", "3.11", "3.12"] - defaults: - run: - working-directory: library - - steps: - - name: Checkout library code - uses: actions/checkout@v4 - with: - path: library - - name: Read backend version - id: read-backend-version - run: echo "GEOENGINE_VERSION=$(cat .github/.backend_git_ref)" >> $GITHUB_OUTPUT - - name: Checkout Geo Engine code - uses: actions/checkout@v4 - with: - repository: geo-engine/geoengine - ref: ${{ steps.read-backend-version.outputs.GEOENGINE_VERSION }} - path: backend - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - name: Install lld & GDAL & Protobuf - run: | - sudo apt-get update - sudo apt-get install lld libgdal-dev gdal-bin build-essential clang curl protobuf-compiler libgeos-dev libproj-dev - sudo apt-get clean - export C_INCLUDE_PATH=/usr/include/gdal:$C_INCLUDE_PATH - export CPLUS_INCLUDE_PATH=/usr/include/gdal:$CPLUS_INCLUDE_PATH - sudo ldconfig - - name: Install Rustup - run: | - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y - echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install -e . - pip install -e .[dev] - - name: Check Formatting - run: | - python -m pycodestyle - - name: Lint code - run: | - python -m pylint geoengine - - name: Type-check code - run: | - python -m mypy geoengine - - name: Build - run: python -m build . - - name: Install test dependencies - run: | - pip install -e .[test] - - name: Lint tests - run: | - python -m pylint tests - - name: Type-check tests - run: | - python -m mypy tests - - name: Test - run: pytest - env: - GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend - GEOENGINE_TEST_BUILD_TYPE: "release" - - name: Examples - run: | - python -m pip install -e .[examples] - python test_all_notebooks.py - env: - GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend - GEOENGINE_TEST_BUILD_TYPE: "release" + with: + python-version: ${{ matrix.python-version }} + use-uv: false + coverage: false # Checks the library using minimum version resolution # `uv` has this feature built-in, c.f. https://github.com/astral-sh/uv check-min-version: - runs-on: ubuntu-22.04 - - services: - postgres: - image: postgis/postgis - env: - POSTGRES_USER: geoengine - POSTGRES_PASSWORD: geoengine - POSTGRES_DB: geoengine - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - - defaults: - run: - working-directory: library - - env: - # use minimum supported versions from https://devguide.python.org/versions/ - python-version: "3.9" - # lowest compatible versions for all direct dependencies - # cf., https://github.com/astral-sh/uv#resolution-strategy - resolution: "lowest-direct" - - steps: - - name: Checkout library code - uses: actions/checkout@v4 - with: - path: library - - name: Read backend version - id: read-backend-version - run: echo "GEOENGINE_VERSION=$(cat .github/.backend_git_ref)" >> $GITHUB_OUTPUT - - name: Checkout Geo Engine code - uses: actions/checkout@v4 - with: - repository: geo-engine/geoengine - ref: ${{ steps.read-backend-version.outputs.GEOENGINE_VERSION }} - path: backend - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - name: Install lld & GDAL & Protobuf - run: | - sudo apt-get update - sudo apt-get install lld libgdal-dev gdal-bin build-essential clang curl protobuf-compiler libgeos-dev libproj-dev - sudo apt-get clean - export C_INCLUDE_PATH=/usr/include/gdal:$C_INCLUDE_PATH - export CPLUS_INCLUDE_PATH=/usr/include/gdal:$CPLUS_INCLUDE_PATH - sudo ldconfig - - name: Install Rustup - run: | - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y - echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH - - name: Set up Python ${{ env.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ env.python-version }} - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install uv - - uv venv - source .venv/bin/activate + uses: geo-engine/geoengine-python/.github/workflows/test-python.yml@reusable-workflow - uv pip install --resolution=${{ env.resolution }} -e . - uv pip install --resolution=${{ env.resolution }} -e .[dev] - - name: Build - run: | - source .venv/bin/activate - python -m build . - - name: Install test dependencies - run: | - source .venv/bin/activate - uv pip install --resolution=${{ env.resolution }} -e .[test] - - name: Test - run: | - source .venv/bin/activate - pytest --cov=geoengine --cov-report=lcov - env: - GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend - GEOENGINE_TEST_BUILD_TYPE: "release" - - name: Upload coverage to Coveralls - uses: coverallsapp/github-action@v2 - with: - base-path: library - - name: Examples - run: | - source .venv/bin/activate - uv pip install --resolution=${{ env.resolution }} -e .[examples] - python test_all_notebooks.py - env: - GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend - GEOENGINE_TEST_BUILD_TYPE: "release" + with: + python-version: 3.9 + use-uv: true + coverage: true diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml new file mode 100644 index 0000000..86b67e4 --- /dev/null +++ b/.github/workflows/test-python.yml @@ -0,0 +1,153 @@ +name: Test Python Library + +on: + workflow_call: + inputs: + python-version: + type: string + required: true + description: 'Python version to use, e.g., "3.9"' + use-uv: + type: boolean + default: false + description: 'Use `uv` for minimum version resolution' + coverage: + type: boolean + default: false + description: 'Generate coverage report' + +jobs: + check: + runs-on: ubuntu-22.04 + + services: + postgres: + image: postgis/postgis + env: + POSTGRES_USER: geoengine + POSTGRES_PASSWORD: geoengine + POSTGRES_DB: geoengine + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + defaults: + run: + working-directory: library + + steps: + - name: Checkout library code + uses: actions/checkout@v4 + with: + path: library + - name: Setup variables + id: vars + run: | + echo "GEOENGINE_VERSION=$(cat .github/.backend_git_ref)" >> $GITHUB_OUTPUT + if ${{ inputs.use-uv }}; then + echo "PIP_INSTALL=uv pip install --resolution=lowest-direct" >> $GITHUB_OUTPUT + echo "VENV_CALL=source .venv/bin/activate" >> $GITHUB_OUTPUT + else + echo "PIP_INSTALL=pip install" >> $GITHUB_OUTPUT + echo "VENV_CALL=" >> $GITHUB_OUTPUT + fi + if ${{ inputs.coverage }}; then + echo "COVERAGE_COMMAND=--cov=geoengine --cov-report=lcov" >> $GITHUB_OUTPUT + else + echo "COVERAGE_COMMAND=" >> $GITHUB_OUTPUT + fi + - name: Checkout Geo Engine code + uses: actions/checkout@v4 + with: + repository: geo-engine/geoengine + ref: ${{ steps.vars.outputs.GEOENGINE_VERSION }} + path: backend + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + - name: Install lld & GDAL & Protobuf + run: | + sudo apt-get update + sudo apt-get install lld libgdal-dev gdal-bin build-essential clang curl protobuf-compiler libgeos-dev libproj-dev + sudo apt-get clean + export C_INCLUDE_PATH=/usr/include/gdal:$C_INCLUDE_PATH + export CPLUS_INCLUDE_PATH=/usr/include/gdal:$CPLUS_INCLUDE_PATH + sudo ldconfig + - name: Install Rustup + run: | + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y + echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH + - name: Set up Python ${{ inputs.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python-version }} + - name: Upgrade PIP + run: python -m pip install --upgrade pip + - name: Setup UV and create venv + if: ${{ inputs.use-uv }} + run: | + pip install uv + uv venv + - name: Install build dependencies + run: | + ${{ steps.vars.outputs.VENV_CALL }} + ${{ steps.vars.outputs.PIP_INSTALL }} -e .[dev] + - name: Check Formatting + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m pycodestyle + - name: Lint code + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m pylint geoengine + - name: Type-check code + # mypy seems buggy with uv + if: ${{ !inputs.use-uv }} + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m mypy geoengine + - name: Build + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m build . + - name: Install test dependencies + run: | + ${{ steps.vars.outputs.VENV_CALL }} + ${{ steps.vars.outputs.PIP_INSTALL }} -e .[test] + - name: Lint tests + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m pylint tests + - name: Type-check tests + # mypy seems buggy with uv + if: ${{ !inputs.use-uv }} + run: | + ${{ steps.vars.outputs.VENV_CALL }} + python -m mypy tests + - name: Test + run: | + ${{ steps.vars.outputs.VENV_CALL }} + pytest ${{ steps.vars.outputs.COVERAGE_COMMAND }} + env: + GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend + GEOENGINE_TEST_BUILD_TYPE: "release" + - name: Upload coverage to Coveralls + if: ${{ inputs.coverage }} + uses: coverallsapp/github-action@v2 + with: + base-path: library + - name: Examples + run: | + ${{ steps.vars.outputs.VENV_CALL }} + ${{ steps.vars.outputs.PIP_INSTALL }} -e .[examples] + python test_all_notebooks.py + env: + GEOENGINE_TEST_CODE_PATH: ${{ github.workspace }}/backend + GEOENGINE_TEST_BUILD_TYPE: "release" diff --git a/.gitignore b/.gitignore index 145f9ad..29bd99a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ __pycache__ # Virtual Environments env env-* +.venv # Private files .pypirc diff --git a/README.md b/README.md index eda2ab4..a4aa3b8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Geo Engine Python Package [![CI](https://github.com/geo-engine/geoengine-python/actions/workflows/ci.yml/badge.svg)](https://github.com/geo-engine/geoengine-python/actions/workflows/ci.yml) +[![Coverage Status](https://coveralls.io/repos/github/geo-engine/geoengine-python/badge.svg)](https://coveralls.io/github/geo-engine/geoengine-python) +[![Documentation](https://img.shields.io/badge/documentation-python.docs.geoengine.io-blue)](https://python.docs.geoengine.io/) This package allows easy access to Geo Engine functionality from Python environments. diff --git a/setup.cfg b/setup.cfg index b81c141..d489480 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,7 +40,7 @@ install_requires = [options.extras_require] dev = build >=0.7,<0.11 - mypy >=0.97,<2.0 + mypy >=1.14.1,<2.0 pdoc3 >=0.10,<0.11 pycodestyle >=2.8,<3 # formatter pylint >=3.3,<4 # code linter @@ -76,4 +76,10 @@ ignore = E501, # one of W503 or W504 must be ignored W503 -exclude = build,env* +exclude = + # build dir + build, + # common venv dir + env*, + # hidden dirs + .?*