Awesome Earth Observation Instruments in Python
Awesome Earth Observation Instruments Catalogue: https://github.com/awesome-spectral-indices/awesome-earth-observation-instruments
GitHub: https://github.com/awesome-spectral-indices/xeo
About xeo
xeo is the Python interface to the Awesome Earth Observation Instruments catalogue. It turns the catalogue into a small, exploratory API for discovering instruments, inspecting their metadata, searching across the collection, and loading spectral bands and spectral response functions as pandas DataFrames when they are available.
A snapshot of the catalogue is bundled with each xeo release. This keeps catalogue exploration local and makes it straightforward to use instrument metadata in Python workflows.
What is the Awesome Earth Observation Instruments catalogue?
Awesome Earth Observation Instruments is a community-driven, machine-readable catalogue of instruments used to observe Earth. It organizes spectral, spatial, temporal, operational, platform, and data-access metadata under a consistent schema so that instruments from different missions and operators can be discovered and compared.
The catalogue is the source of the instrument records; xeo is the Python interface to those records. Contributions to instrument metadata, bands, SRFs, or catalogue schemas belong in the catalogue repository, while contributions to the Python API and its documentation belong here.
Installation
Install xeo from PyPI:
python -m pip install xeo
Plotting is optional. Install xeo with Matplotlib support when you need it:
python -m pip install "xeo[plot]"
Or install it from conda-forge:
conda install -c conda-forge xeo
To use the current development version:
git clone https://github.com/awesome-spectral-indices/xeo.git
cd xeo
python -m pip install --editable .
xeo requires Python 3.10 or newer.
Getting started
Explore the catalogue
Import xeo to access the bundled catalogue and its instrument collection:
import xeo
print(xeo.catalogue)
print(f"Catalogue version: {xeo.catalogue.version}")
print(f"Number of instruments: {len(xeo.instruments)}")
print(list(xeo.instruments))
xeo.instruments is a frozen collection keyed by instrument identifier. Instruments support both attribute and mapping access:
msi = xeo.instruments.MSI_S2A
assert msi is xeo.instruments["MSI_S2A"]
print(msi.name)
print(msi.platform)
print(msi.operator)
print(msi.contributors)
print(msi.status)
Inspect instrument metadata
Required catalogue fields are exposed as attributes. Optional and domain-specific metadata can be discovered through extensions, while relationships connect an instrument to its family and platform companions:
print(msi.extension_names)
print(msi.extensions["spectral"].keys())
print(msi.family)
print(msi.platform_companions)
print(msi.references)
Use msi.data to inspect the original record, or msi.to_dict() when you need an independent copy that can be modified safely.
Search for instruments
Catalogue.search() returns an Instruments collection containing every match. Different properties are combined with AND, while lists mean “match any of these values”:
results = xeo.catalogue.search(
operator=["ESA", "NASA"],
platform_type="satellite",
status="operational",
has_bands=True,
)
print(list(results))
Use has_bands and has_srf to filter by spectral-data availability. For start_date, an inclusive YYYY-MM-DD/YYYY-MM-DD interval avoids requiring an exact date:
launched = xeo.catalogue.search(
start_date="2000-01-01/2003-01-01"
)
Load spectral bands
When band definitions are available, bands() returns a DataFrame indexed by band identifier:
if msi.has_bands:
bands = msi.bands()
print(bands.loc[["B2", "B3", "B4"], ["center_wavelength", "bandwidth"]])
Wavelengths and bandwidths are expressed in nanometres, and band-level ground sampling distances are expressed in metres. Thermal bands may also include noise-equivalent temperature difference values in the ne_delta_t column.
Load spectral response functions
When an SRF is available, srf() returns a DataFrame with a wavelength column and one response column per band:
if msi.has_srf:
srf = msi.srf()
print(srf[["wavelength", "B2", "B3", "B4"]].head())
SRFs are external CSV resources. The first srf() call downloads the file into a per-user cache organized by catalogue version; subsequent calls reuse that local file and work offline. Use msi.srf(refresh=True) to replace the cached file with the current resource. Set the XEO_CACHE_DIR environment variable when the cache should live in a custom writable location.
Both bands() and srf() return None when the requested data is not available. Checking has_srf reads catalogue metadata only and never downloads anything.
Plot bands and spectral response functions
Install the optional plotting extra, then pass one instrument id, a list of ids, a dictionary selecting bands, or a list of per-instrument dictionaries:
bands_ax = xeo.plot_bands({"MSI_S2A": ["B2", "B3", "B4", "B8"]})
srf_ax = xeo.plot_srf(["MSI_S2A", "OLI_L8"], figsize=(10, 6))
Dictionary selections can attach native Matplotlib styles to individual bands:
ax = xeo.plot_srf(
[
{
"MSI_S2A": [
{"B4": {"color": "red", "linestyle": "--", "linewidth": 2}}
]
},
{"OLI_L8": [{"B5": {"color": "blue", "linewidth": 2}}]},
],
title="Selected red and near-infrared responses",
)
Both functions return a Matplotlib Axes, so the complete Matplotlib API remains available for further customization.
Discover data access points
get_data_access() retrieves the catalogue entry for a provider and processing level. It defaults to the primary Google Earth Engine collection:
earth_engine = msi.get_data_access()
planetary_computer = msi.get_data_access("planetary_computer", "boa")
cdse = msi.get_data_access("cdse", "toa")
Available providers are ee, planetary_computer, cdse, and eopf; supported processing and product levels are primary, boa, toa, raw, lst, wst, grd, rtc, and slc. An available entry is returned as a dictionary with stac_endpoint, collection, and docs. Valid combinations that are not available for an instrument return None.
Work with raw catalogue data
The object API is intended for exploration, but the complete JSON-compatible catalogue is also available for custom workflows:
raw_record = xeo.catalogue.data["instruments"]["MSI_S2A"]
catalogue_copy = xeo.catalogue.to_dict()
Treat .data as read-only. Use .to_dict() when downstream code needs to modify a catalogue or instrument dictionary.
Tutorials
The tutorial notebooks provide complete, executable examples:
- Getting started
- Exploring instruments
- Spectral bands
- Spectral response functions
- Raw data and DataFrame workflows
- Data access
- Advanced search
- Plotting spectral data
Contributing
Contributions are welcome. See CONTRIBUTING.md for development setup, testing, documentation guidance, and where to propose catalogue-data changes.
License
xeo is available under the MIT License.
Metadata
Release files for xeo 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| xeo-0.3.0.tar.gz | 41.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xeo-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.5 kB
Release files / xeo-0.3.0.tar.gz
| Download URL | xeo-0.3.0.tar.gz |
|---|---|
| Size | 41.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff1f5d10d67b00d0117406797737bac9b11660610d23e9b7be7f82625e84edfc
|
|
BLAKE2b-256 checksum How to use checksums |
304fbe5cb2d7c754730ab0ff9a20445cbadddcd1b165642b27d76e9895e13e04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / xeo-0.3.0-py3-none-any.whl
| Download URL | xeo-0.3.0-py3-none-any.whl |
|---|---|
| Size | 35.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2f8dc1d87060f44ceda4a0f09cc0a8f2c68f775f14e05ae0fe642f10e67b66cb
|
|
BLAKE2b-256 checksum How to use checksums |
ad239997cea5abe2cb056612a17d7cbb0b9e7a663e7ec2950673545f9c8b124c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency log