eo-learn: the newest release is from September 2024
Earth observation processing framework for machine learning in Python
At a glance
- What is it?
- eo-learn is Sentinel Hub's Python framework for turning satellite imagery into machine learning data, organised as a chain of tasks over a data patch. It is also a package whose published version is nearly two years behind its repository, with a release Makefile whose phony declaration does not work and a source distribution that lists the wrong licence filename.
- Who is it for?
- eo-learn suits someone already working with Sentinel Hub data who wants cloud masking, co-registration, feature extraction and classification as composable tasks rather than a bespoke pipeline. Three things to know before you rely on it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 31 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The published version is a year behind the repository
The release history has a gap that matters more than the version numbers.
Three releases are visible: v1.5.5 on 2024-06-19, v1.5.6 on 2024-06-26 and v1.5.7 on 2024-09-27. That is the last tagged release.
The last push to the repository is dated 2026-09-09. So whatever has changed in this codebase over the past year is not in the package you install, and the gap between a published version and a moving default branch is the first thing to establish before you build on either one.
The project is not abandoned in the sense of being archived. What it has is a cadence that has stopped: three releases clustered in three weeks in mid-2024, then nothing. Anyone planning a pipeline needs to decide between pinning the published version and tracking the default branch, because they are different pieces of software with the same name.
The branch itself is `master` rather than `main`, which matters for anyone writing automation against it. And the package is on both PyPI and conda-forge, with a Zenodo DOI and a credits file, so the project is set up for citation even though the citation target is two years old.
One dependency set for Python 3.8 and a different one above it
The project metadata carries conditional dependencies, and the condition is the interpreter version.
requires-python = ">= 3.8"
dependencies = [
"geopandas>=0.14.4,<1; python_version>='3.9'",
"geopandas>=0.11.0,<1; python_version<'3.9'",
"fiona>=1.8.18; python_version>='3.9'",
]So the supported floor is 3.8, and anyone on 3.8 gets geopandas 0.11 rather than 0.14. That is a wide gap between the oldest and newest supported interpreters, and it exists because geopandas itself moved its own floor.
The floor has a second consequence. Python 3.8 is past end of life, and a package that still supports it is carrying a dependency branch that no longer receives security fixes. For a library that reads remote sensing data and runs cloud detection, that is worth weighing rather than ignoring.
Everything else in the list is unconditional: the Sentinel Hub client at a floor of 3.9, rasterio, shapely, OpenCV's headless build, affine, an affine transform helper, NumPy at 1.20 or newer, a date parser, a progress bar and typing extensions. Plus an Amazon S3 filesystem layer, twice over, once plain and once through a separate library.
The framework is therefore not standalone. It is coupled to one vendor's client at a specific floor, which is the right design for its users and a constraint for anyone else.
The Makefile declares .PHONY with a variable that is never set
The repository's Makefile exists only to publish the package, and it has two targets.
.PHONY: $(PACKAGES:test)
help:
@echo "Use 'make test-upload' to upload the package to testPyPi"
@echo "Use 'make upload' to upload the package to PyPi"
upload:
rm -r dist | true
python -m build --sdist --wheel
twine upload --skip-existing dist/*
# For testing:
test-upload:
rm -r dist | true
python -m build --sdist --wheel
twine upload --repository testpypi --skip-existing dist/*Both targets begin by removing the distribution directory. That is exactly the case phony targets exist for, and the declaration is written as a variable expansion with no default.
`PACKAGES` is never assigned anywhere in the file, so the line expands to a single colon followed by the word `test`. It declares one phony target named `test`, which does not exist, and does not declare `upload`, `test-upload` or even `help`.
The `rm -r dist | true` also has its own problem: it pipes stderr away, so a missing directory is silently ignored, which is the intent, but it also hides a permission failure on an existing directory. Either way the intent is to never fail the build for a missing directory.
The net effect is that the protection against a file named `upload` shadowing the target is not actually in place. It is the kind of defect that appears as a permissions error on a maintainer's machine rather than as a build failure.
The source distribution includes a licence filename the repository does not have
The build configuration names one licence file and ships another.
[tool.hatch.build.targets.sdist]
include = ['/README.md', '/LICENSE.md', '/eolearn']
[project]
license = { file = "LICENSE" }The metadata points at a file called `LICENSE`. The source distribution include list points at `LICENSE.md`, with an extension. The repository root contains a file called `LICENSE`, with no extension.
So the file the project metadata resolves is present, and the file the source distribution includes is not. A source distribution built from this configuration would ship without the licence text, while a wheel built from it would carry it.
That asymmetry matters in practice. Most people install the wheel. People who vendor, audit or redistribute an sdist get a tarball whose legal file is missing, which is the sort of thing a compliance review catches long after anyone remembers this commit.
The rest of the build configuration is careful in a way that makes this more noticeable. The backend is hatchling, the version is dynamic and read from a path, and both the source distribution and the wheel have explicit include lists rather than defaults.
[tool.hatch.version]
path = 'eolearn/__init__.py'Reading the version from the package's own initialisation file is the modern pattern, and it means the version lives in one place rather than in two.
Windows means four binary wheels from an unofficial collection
Three operating systems, three installation stories, and the Windows one is the odd one out.
Linux is straightforward. Install the system libraries first:
sudo apt-get install gcc libgdal-dev graphviz proj-bin libproj-dev libspatialindex-devmacOS uses Homebrew for the same set, adding cmake.
Windows asks you to install four packages from a page described as an unofficial Windows wheels repository, hosted on a personal directory at a university:
gdal
rasterio
shapely
fionaThose are compiled geospatial libraries with binary wheels. On Windows, unlike Linux and macOS, there is no system package manager path, so the documented route is to trust a third party's wheel collection and get four compiled extensions onto your machine from it.
The framework itself is a geospatial library, so this is not an optional extra; the core install depends on it. Anyone with a policy about third-party binary sources should read the alternative, which is the container image.
Two images are published, one carrying a Jupyter environment and one additionally carrying every example notebook and its data, both on port 8888, both buildable from two named Dockerfiles in the repository.
Seven extras, and one of them does three unrelated jobs
The optional dependencies are the package's main extension mechanism, and the naming is inconsistent with the modules they support.
The install syntax is the standard bracket form:
pip install "eo-learn[EXTRA]"
pip install "eo-learn[VISUALIZATION]"The list has seven entries, all in capital letters: `RAY` for the Ray library and its dependencies, `ZARR` for chunked timestamp saving and loading, `VISUALIZATION` for plotting, `FULL` for everything described so far, `DOCS` for building the documentation, and `DEV` for testing and code contribution.
The seventh is the awkward one. `EXTRA` covers interpolation-specific dependencies, clustering-specific dependencies, and the `s2cloudless` package used for cloud masking. Those are three unrelated capabilities grouped under one name, and it is the extra the page uses as its first example.
So a user who wants cloud masking, which is the most commonly needed capability in remote sensing pipelines, installs an extra whose name tells them nothing about it. The names also do not map onto the module list, where cloud masking lives in the `mask` module and the extras live under an `extra` subfolder inside modules rather than at the package level.
The stated reason for having extras at all is to keep the default installation light, which is reasonable for a library with this many optional dependencies.
Classifiers claim production stability and stop at Python 3.11
The classifier list tells one story and the version floor tells another.
The development status is 5, production or stable. The supported operating systems are MacOS, Windows and Unix. The Python classifiers are the bare 3 line plus 3.8, 3.9, 3.10 and 3.11.
So the package claims to be production stable, supports a Python floor of 3.8, and has said nothing about 3.12 or 3.13. Newer interpreters are neither declared nor excluded; the classifiers simply stop.
That is a small inaccuracy, but it sits next to the release gap. A classifier claiming production stability invites a reader to skip the version history, and the version history is where the relevant information is.
The rest of the packaging is in good order. The author field names the Sinergise Earth observation research team, which says who maintains it. The topics are declared as scientific and engineering work in GIS and image processing. And the package structure is modular in a way that is genuinely useful: a core module with the three building blocks, plus separate modules for co-registration, features, geometry, input and output, masking, machine learning tools and visualisation, with optional dependencies kept in `extra` subfolders so the default install stays small.
The three building blocks in the core are the whole design: a patch of data, a task that operates on it, and a workflow that chains tasks.
Editorial conclusion
eo-learn suits someone already working with Sentinel Hub data who wants cloud masking, co-registration, feature extraction and classification as composable tasks rather than a bespoke pipeline. Three things to know before you rely on it. The published package is from 2024, so what you install from PyPI or conda-forge is not what the repository has become, and the framework is coupled to a Sentinel Hub client at a specific floor. The supported Python range starts at 3.8, which means an older geospatial stack on the oldest interpreters. And on Windows the documented route installs four compiled geospatial libraries from an unofficial wheel collection, so the container image is the safer path there. The task model itself is the part worth copying.
Frequently asked questions
What is eo-learn and what are its three core building blocks?
It is a Python framework for processing satellite imagery, and its core module implements a patch of data, a task that operates on it, and a workflow that chains tasks. Tasks cover co-registration, features, geometry, input and output, masking, machine learning tools and visualisation.
How current is the published eo-learn package?
The newest release is v1.5.7 from 2024-09-27, preceded by v1.5.6 and v1.5.5 in June 2024. The last push to the repository is dated 2026-09-09, on the master branch.
Which Python versions does eo-learn support?
The floor is 3.8. On Python 3.8 the dependency set differs, with geopandas 0.11 rather than 0.14, and the classifiers list 3.8 through 3.11 without saying anything about newer interpreters.
How do I install eo-learn on Windows?
By installing gdal, rasterio, shapely and fiona from the unofficial Windows wheels repository the page links to. Linux and macOS install equivalent system libraries through apt or Homebrew instead.
What do the eo-learn optional extras install?
Seven groups, all in capitals: RAY, ZARR, EXTRA, VISUALIZATION, FULL, DOCS and DEV. The EXTRA group is the one the documentation uses as its example, and it covers interpolation, clustering and the s2cloudless package used for cloud masking.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sentinel-hub-eo-learn)