Skip to content

Commit a0041b8

Browse files
authored
Merge pull request #212 from geo-engine/docker-ml-app
interactive ml container
2 parents 3cf1c57 + c1e85cd commit a0041b8

File tree

8 files changed

+105
-1775
lines changed

8 files changed

+105
-1775
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Setup a Debian 12 based image with a Python virtualenv
2+
FROM debian:12-slim AS build
3+
RUN apt-get update && \
4+
apt-get install --no-install-suggests --no-install-recommends --yes python3-venv gcc libpython3-dev && \
5+
python3 -m venv /venv && \
6+
/venv/bin/pip install --upgrade pip setuptools wheel
7+
8+
# Install Geo Engine library and its dependencies
9+
FROM build AS build-venv
10+
COPY pyproject.toml setup.cfg setup.py /library/
11+
COPY geoengine /library/geoengine
12+
WORKDIR /library
13+
RUN /venv/bin/pip install --disable-pip-version-check .[dev,test,examples]
14+
15+
# Copy the virtualenv into a distroless image
16+
# Hint: Use the `:debug` tag to get a shell in the image
17+
FROM gcr.io/distroless/python3-debian12
18+
COPY --from=build-venv /venv /venv
19+
20+
# Copy the example notebook to run
21+
COPY examples/interactive_ml /app
22+
23+
WORKDIR /app
24+
25+
ENV GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api
26+
ENV GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN>
27+
28+
EXPOSE 8866
29+
30+
ENTRYPOINT [ \
31+
"/venv/bin/python3", \
32+
"-m", \
33+
"voila", \
34+
"--no-browser", \
35+
"--Voila.ip='0.0.0.0'", \
36+
"app/Simple Random Forest Two-Class Classifier on Sentinel-2 Images.ipynb" \
37+
]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Interactive ML App
2+
3+
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.
4+
5+
## Local setup
6+
7+
To run the app locally, you need to install the dependencies and start the app. You can install the dependencies with:
8+
9+
```bash
10+
pip install --disable-pip-version-check -e .[dev,test,examples]
11+
12+
GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api \
13+
GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN> \
14+
./examples/interactive_ml/app/app.sh
15+
```
16+
17+
The app will be available at [http://localhost:8866](http://localhost:8866).
18+
19+
## Container setup
20+
21+
To run the app in a container, you need to build the container image and start the container.
22+
You can build the container image with:
23+
24+
```bash
25+
./examples/interactive_ml/app/build.sh
26+
27+
podman run --rm \
28+
-p 8866:8866 \
29+
-e GEOENGINE_INSTANCE_URL=https://zentrale.app.geoengine.io/api \
30+
-e GEOENGINE_SESSION_TOKEN=<SESSION_TOKEN> \
31+
geoengine-interactive-ml:latest
32+
```
33+
34+
### Upload to quay.io
35+
36+
To upload the container image to quay.io, you need to log in and push the image.
37+
You can do this with:
38+
39+
```bash
40+
podman login quay.io
41+
podman push geoengine-interactive-ml:latest quay.io/geoengine/geoengine-interactive-ml:latest
42+
```

examples/interactive_ml/app/Simple Random Forest Two-Class Classifier on Sentinel-2 Images.ipynb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"outputs": [],
1919
"source": [
2020
"import ipyvuetify as vue\n",
21+
"import IPython.display\n",
22+
"import base64\n",
2123
"from dataclasses import dataclass\n",
2224
"from collections.abc import Callable, Coroutine\n",
2325
"from enum import Enum\n",
@@ -341,6 +343,22 @@
341343
"\n"
342344
]
343345
},
346+
{
347+
"cell_type": "code",
348+
"execution_count": null,
349+
"metadata": {},
350+
"outputs": [],
351+
"source": [
352+
"with open(\"assets/favicon.ico\", \"rb\") as image_file:\n",
353+
" favicon = base64.b64encode(image_file.read()).decode()\n",
354+
"\n",
355+
"favicon_changer = IPython.display.Javascript(f'''\n",
356+
" document.querySelector(\"link[rel='icon']\").href = \"data:image/x-icon;base64,{favicon}\";\n",
357+
"''')\n",
358+
"\n",
359+
"IPython.display.display(favicon_changer)"
360+
]
361+
},
344362
{
345363
"cell_type": "code",
346364
"execution_count": null,
@@ -399,7 +417,7 @@
399417
" padding: 0 !important;\n",
400418
" margin: 0 !important;\n",
401419
" }\n",
402-
"</style>\n"
420+
"</style>"
403421
]
404422
},
405423
{
@@ -489,7 +507,7 @@
489507
" self.error_bar,\n",
490508
" vue.Html(tag='br'),\n",
491509
" ]),\n",
492-
" vue.Footer(children=[vue.Col(children=['2024 – Geo Engine GmbH'], class_='text-center')], app=True),\n",
510+
" vue.Footer(children=[vue.Col(children=['2025 – Geo Engine GmbH'], class_='text-center')], app=True),\n",
493511
" ]\n",
494512
"\n",
495513
" def register_location_button(self, callback: Callable[[Location, str, str], None]) -> None:\n",
@@ -742,7 +760,7 @@
742760
"name": "python",
743761
"nbconvert_exporter": "python",
744762
"pygments_lexer": "ipython3",
745-
"version": "3.11.3"
763+
"version": "3.10.12"
746764
}
747765
},
748766
"nbformat": 4,
13.2 KB
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4+
5+
podman build -f $SCRIPT_DIR/Dockerfile --tag geoengine-interactive-ml:latest .

examples/ml_water_bodies/labeling.py

Lines changed: 0 additions & 201 deletions
This file was deleted.

0 commit comments

Comments
 (0)