Skip to content

Commit

Permalink
Merge pull request #211 from geo-engine/ge_test
Browse files Browse the repository at this point in the history
test geo engine against actual instance in unit tests
  • Loading branch information
michaelmattig authored Jan 13, 2025
2 parents ef00121 + 2ff8af1 commit 2848c68
Show file tree
Hide file tree
Showing 28 changed files with 913 additions and 2,064 deletions.
1 change: 1 addition & 0 deletions .github/.backend_git_ref
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main
143 changes: 129 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,63 @@ 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

strategy:
fail-fast: false
matrix:
# 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:
- uses: actions/checkout@v3
- name: APT update
run: sudo apt-get update
- name: Install system dependencies
run: sudo apt-get install libgeos-dev libproj-dev
- 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:
Expand Down Expand Up @@ -53,12 +98,37 @@ jobs:
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"

# 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"
Expand All @@ -67,11 +137,41 @@ jobs:
resolution: "lowest-direct"

steps:
- uses: actions/checkout@v3
- name: APT update
run: sudo apt-get update
- name: Install system dependencies
run: sudo apt-get install libgeos-dev libproj-dev
- 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:
Expand All @@ -84,17 +184,32 @@ jobs:
uv venv
source .venv/bin/activate
uv pip install --resolution=${{ env.resolution}} -e .
uv pip install --resolution=${{ env.resolution}} -e .[dev]
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]
uv pip install --resolution=${{ env.resolution }} -e .[test]
- name: Test
run: |
source .venv/bin/activate
pytest
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"
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ Run tests with:
pytest
```

#### Test instance

You have to set the environment variable `GEOENGINE_TEST_CODE_PATH` to the code folder of the Geo Engine instance you want to test against.
Dotenv is supported, so you can create a `.env` file in the root of the project.

#### Coverage

You can check the coverage with:

```bash
pytest --cov=geoengine
```

### Test examples

You can test the examples with:

```bash
python3 -m pip install -e .[examples]
./test_all_notebooks.py
```

Or you can test a single example with:

```bash
./test_notebook.py examples/ndvi_ports.ipynb
```

## Dependencies

Since we use `cartopy`, you need to have the following system dependencies installed.
Expand Down
12 changes: 8 additions & 4 deletions check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ function echoerr() {
echo "$@" 1>&2;
}

echoerr "Running tests"

pytest

echoerr "Check code style"

python3 -m pycodestyle
Expand All @@ -28,3 +24,11 @@ echoerr "Check code with type checker"

python3 -m mypy geoengine
python3 -m mypy tests

echoerr "Running tests"

pytest

echoerr "Running examples"

python3 test_all_notebooks.py
37 changes: 37 additions & 0 deletions examples/interactive_ml/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Setup a Debian 12 based image with a Python virtualenv
FROM debian:12-slim AS build
RUN apt-get update && \
apt-get install --no-install-suggests --no-install-recommends --yes python3-venv gcc libpython3-dev && \
python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip setuptools wheel

# Install Geo Engine library and its dependencies
FROM build AS build-venv
COPY pyproject.toml setup.cfg setup.py /library/
COPY geoengine /library/geoengine
WORKDIR /library
RUN /venv/bin/pip install --disable-pip-version-check .[dev,test,examples]

# Copy the virtualenv into a distroless image
# Hint: Use the `:debug` tag to get a shell in the image
FROM gcr.io/distroless/python3-debian12
COPY --from=build-venv /venv /venv

# Copy the example notebook to run
COPY examples/interactive_ml /app

WORKDIR /app

ENV GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api
ENV GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN>

EXPOSE 8866

ENTRYPOINT [ \
"/venv/bin/python3", \
"-m", \
"voila", \
"--no-browser", \
"--Voila.ip='0.0.0.0'", \
"app/Simple Random Forest Two-Class Classifier on Sentinel-2 Images.ipynb" \
]
42 changes: 42 additions & 0 deletions examples/interactive_ml/app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Interactive ML App

This app demonstrates a complete workflow for binary classification using Sentinel-2 satellite imagery and a Random Forest classifier. The workflow includes data acquisition, preprocessing, model training, and result visualization. Initially, the environment is set up and necessary libraries are imported. The spatial and temporal bounds for the data query are then defined through a query rectangle. A workflow is created to fetch and preprocess Sentinel-2 data, which is followed by the use of a labeling tool to create training data for water and non-water classes.

## Local setup

To run the app locally, you need to install the dependencies and start the app. You can install the dependencies with:

```bash
pip install --disable-pip-version-check -e .[dev,test,examples]

GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api \
GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN> \
./examples/interactive_ml/app/app.sh
```

The app will be available at [http://localhost:8866](http://localhost:8866).

## Container setup

To run the app in a container, you need to build the container image and start the container.
You can build the container image with:

```bash
./examples/interactive_ml/app/build.sh

podman run --rm \
-p 8866:8866 \
-e GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api \
-e GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN> \
geoengine-interactive-ml:latest
```

### Upload to quay.io

To upload the container image to quay.io, you need to log in and push the image.
You can do this with:

```bash
podman login quay.io
podman push geoengine-interactive-ml:latest quay.io/geoengine/geoengine-interactive-ml:latest
```
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"outputs": [],
"source": [
"import ipyvuetify as vue\n",
"import IPython.display\n",
"import base64\n",
"from dataclasses import dataclass\n",
"from collections.abc import Callable, Coroutine\n",
"from enum import Enum\n",
Expand Down Expand Up @@ -341,6 +343,22 @@
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(\"assets/favicon.ico\", \"rb\") as image_file:\n",
" favicon = base64.b64encode(image_file.read()).decode()\n",
"\n",
"favicon_changer = IPython.display.Javascript(f'''\n",
" document.querySelector(\"link[rel='icon']\").href = \"data:image/x-icon;base64,{favicon}\";\n",
"''')\n",
"\n",
"IPython.display.display(favicon_changer)"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -399,7 +417,7 @@
" padding: 0 !important;\n",
" margin: 0 !important;\n",
" }\n",
"</style>\n"
"</style>"
]
},
{
Expand Down Expand Up @@ -489,7 +507,7 @@
" self.error_bar,\n",
" vue.Html(tag='br'),\n",
" ]),\n",
" vue.Footer(children=[vue.Col(children=['2024 – Geo Engine GmbH'], class_='text-center')], app=True),\n",
" vue.Footer(children=[vue.Col(children=['2025 – Geo Engine GmbH'], class_='text-center')], app=True),\n",
" ]\n",
"\n",
" def register_location_button(self, callback: Callable[[Location, str, str], None]) -> None:\n",
Expand Down Expand Up @@ -742,7 +760,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Binary file added examples/interactive_ml/app/assets/favicon.ico
Binary file not shown.
5 changes: 5 additions & 0 deletions examples/interactive_ml/app/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

podman build -f $SCRIPT_DIR/Dockerfile --tag geoengine-interactive-ml:latest .
Loading

0 comments on commit 2848c68

Please sign in to comment.