Skip to main content

Browse and download Sentinel satellite products from the Copernicus Data Space Ecosystem (CDSE)

Project description

Stable

Copernicus Explorer

A Rust client for browsing and downloading Sentinel satellite products from the Copernicus Data Space Ecosystem (CDSE).

Features

  • Search the CDSE catalogue by satellite, product type, date range, cloud cover, tile ID, point, or bounding box
  • Download scenes by name with Bearer-token authentication
  • Batch download multiple products concurrently with configurable parallelism
  • Authenticate against the CDSE OAuth2 identity provider
  • Supports Sentinel-1, Sentinel-2, Sentinel-3, Sentinel-5P, and Sentinel-6
  • Async-first design (tokio) with synchronous blocking wrappers
  • Usable as a Rust library, a CLI, or from Python via native bindings

Prerequisites

  • Rust 1.85+ (edition 2024)
  • A free Copernicus Data Space account (required for authentication and downloads; searching is anonymous)
  • For Python bindings: Python 3.9+, uv (recommended), and maturin

Project structure

The repository is a Cargo workspace with two members:

copernicus_explorer/       Cargo workspace root
  Cargo.toml               Workspace manifest
  copernicus_explorer/     Core Rust library + CLI binary
    Cargo.toml
    src/
      lib.rs               Module declarations and re-exports
      main.rs              CLI binary (clap)
      error.rs             CopernicusError enum (thiserror)
      models.rs            Satellite enum, Product struct (serde)
      geometry.rs          Point, BoundingBox, WKT conversion
      auth.rs              OAuth2 token retrieval (reqwest, async)
      search.rs            SearchQuery builder, OData filter construction (async)
      download.rs          Single & batch download with streaming I/O + progress bars (async)
      blocking.rs          Synchronous wrappers (block_on) for non-async contexts
    examples/
      test_rust_api.rs     Interactive demo: search, download one or all results
  python/                  Python bindings (PyO3 + maturin)
    Cargo.toml
    pyproject.toml
    src/
      lib.rs               #[pymodule] wrapping the core library
    examples/
      test_python_api.py   Interactive demo: search, download one or all results

Building

git clone <repo-url>
cd copernicus_explorer
cargo build --release

The CLI binary is produced at target/release/copernicus_explorer.

CLI usage

copernicus_explorer <COMMAND>

Commands:
  search    Search the CDSE catalogue for satellite products
  download  Download one or more scenes by name
  auth      Test authentication and print a token summary
  help      Print this message or the help of the given subcommand(s)

search

Search the catalogue. Dates default to the last 30 days if omitted.

# Sentinel-2 L2A near Toulouse, max 30% cloud cover
copernicus_explorer search sentinel-2 -p L2A --point 43.6,1.44 -c 30

# Sentinel-1 GRD over the Alps with explicit date range
copernicus_explorer search sentinel-1 -p GRD \
  --bbox 47.5,6.0,45.5,11.0 \
  --start 2026-03-01 --end 2026-03-24

# Sentinel-2 by tile, limit to 3 results
copernicus_explorer search sentinel-2 -p L2A --tile T31TFJ -n 3

Options:

Flag Description
<SATELLITE> sentinel-1, sentinel-2, sentinel-3, sentinel-5p, sentinel-6
-p, --product <TYPE> Product type filter (e.g. L2A, L1C, GRD)
--start <YYYY-MM-DD> Start of acquisition window (default: 30 days ago)
--end <YYYY-MM-DD> End of acquisition window (default: today)
--tile <TILE> Sentinel-2 tile identifier (e.g. T31TFJ)
-c, --cloud <0-100> Maximum cloud cover percentage
--point <LAT,LON> Point geometry (e.g. 43.6,1.44)
--bbox <TLAT,LLON,BLAT,RLON> Bounding box (e.g. 47.5,6.0,45.5,11.0)
-n, --max-results <N> Maximum number of results (default: 10)

auth

Test your credentials. Reads COPERNICUS_USER and COPERNICUS_PASS from the environment, or accepts them as flags.

# From environment variables
export COPERNICUS_USER="you@example.com"
export COPERNICUS_PASS="yourpassword"
copernicus_explorer auth

# Or pass directly
copernicus_explorer auth -u you@example.com -P yourpassword

download

Download one or more scenes by name. Requires authentication.

# Single scene
copernicus_explorer download \
  "S2B_MSIL2A_20260315T105019_N0512_R051_T31TCJ_20260315T144522.SAFE" \
  -o ./data

# Multiple scenes concurrently (max 4 in parallel by default)
copernicus_explorer download \
  "S2B_MSIL2A_20260315T105019_N0512_R051_T31TCJ_20260315T144522.SAFE" \
  "S2A_MSIL2A_20260317T104021_N0512_R008_T31TCJ_20260317T160837.SAFE" \
  -o ./data -j 2

Options:

Flag Description
<SCENES>... One or more full scene names
-o, --output-dir <DIR> Output directory (default: .)
-j, --concurrent <N> Maximum concurrent downloads (default: 4)
-u, --user <USER> Username (or set COPERNICUS_USER)
-P, --pass <PASS> Password (or set COPERNICUS_PASS)

Rust library usage

The library is async-first (tokio). A blocking module provides synchronous wrappers for contexts that don't use an async runtime.

Add to your Cargo.toml:

[dependencies]
copernicus_explorer = { path = "../copernicus_explorer" }
chrono = "0.4"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

Async example (search + batch download)

use chrono::{Duration, Utc};
use copernicus_explorer::{
    Geometry, Point, Products, Satellite, SearchQuery,
    download_products, get_access_token_from_env,
};

#[tokio::main]
async fn main() -> Result<(), copernicus_explorer::CopernicusError> {
    // Search (no authentication required)
    let products = SearchQuery::new(Satellite::Sentinel2)
        .product("L2A")
        .dates(Utc::now() - Duration::days(20), Utc::now())
        .max_cloud_cover(30.0)
        .geometry(Geometry::Point(Point::new(43.6, 1.44)))
        .max_results(5)
        .execute()
        .await?;

    println!("{}", Products(&products));

    // Authenticate and download all results (3 concurrent)
    let token = get_access_token_from_env().await?;
    let results = download_products(&products, "./data".as_ref(), &token, 3).await;

    for (product, result) in products.iter().zip(results.iter()) {
        match result {
            Ok(path) => println!("  OK: {} -> {}", product.name, path.display()),
            Err(e) => println!("  FAILED: {} -> {e}", product.name),
        }
    }

    Ok(())
}

Blocking example

use copernicus_explorer::{Satellite, SearchQuery, blocking};

fn main() -> Result<(), copernicus_explorer::CopernicusError> {
    let products = SearchQuery::new(Satellite::Sentinel2)
        .product("L2A")
        .max_results(5)
        .execute_blocking()?;

    let token = blocking::get_access_token_from_env()?;
    let results = blocking::download_products(&products, "./data".as_ref(), &token, 4);

    for (product, result) in products.iter().zip(results.iter()) {
        match result {
            Ok(path) => println!("  OK: {} -> {}", product.name, path.display()),
            Err(e) => println!("  FAILED: {} -> {e}", product.name),
        }
    }

    Ok(())
}

More examples can be found in rust examples

Python bindings

The python/ crate provides native Python bindings via PyO3 and maturin. The compiled extension runs at full Rust speed with no serialization overhead.

Setup

cd python
uv venv .venv
source .venv/bin/activate
uv pip install maturin
maturin develop

Python usage

Search and display results

from datetime import datetime, timedelta, timezone
import copernicus_explorer_py as ce

query = ce.SearchQuery(ce.Satellite.sentinel2())
query.product("L2A")
query.dates(
    datetime.now(timezone.utc) - timedelta(days=20),
    datetime.now(timezone.utc),
)
query.max_cloud_cover(30.0)
query.geometry_point(ce.Point(43.6, 1.44))
query.max_results(5)

products = query.execute()
ce.print_products(products)

Download a single scene

token = ce.get_access_token_from_env()
path = ce.download_scene(products[0].name, "./data", token)
print(f"Downloaded to {path}")

Batch download with concurrency

token = ce.get_access_token_from_env()
results = ce.download_products(products, "./data", token, max_concurrent=3)

for product, result in zip(products, results):
    if result is not None:
        print(f"  OK: {product.name} -> {result}")
    else:
        print(f"  FAILED: {product.name}")

More examples can be found in python examples

Python API reference

Classes:

Class Constructor Key methods / attributes
Satellite Satellite.sentinel1(), .sentinel2(), .sentinel3(), .sentinel5p(), .sentinel6() .collection_name(), .known_products(), .is_valid_product(str)
SearchQuery SearchQuery(satellite) .product(str), .dates(start, end), .tile(str), .max_cloud_cover(float), .geometry_point(Point), .geometry_bbox(BoundingBox), .max_results(int), .execute()
Product returned by SearchQuery.execute() .name, .id, .acquisition_date, .publication_date, .online, .cloud_cover
Point Point(lat, lon) .lat, .lon
BoundingBox BoundingBox((lat, lon), (lat, lon)) .upper_left, .lower_right

Functions:

Function Description
get_access_token(username, password) Authenticate and return an access token string
get_access_token_from_env() Authenticate using COPERNICUS_USER / COPERNICUS_PASS env vars
download_scene(scene_name, directory, token) Download a single scene; returns the output file path
download_products(products, directory, token, max_concurrent=4) Download multiple products concurrently; returns a list of paths (or None on failure)
get_scene_id(scene_name) Resolve a scene name to its CDSE UUID

Running tests

# Rust unit tests (from workspace root)
cargo test

# Quick Python smoke test
cd python
source .venv/bin/activate
python -c "
import copernicus_explorer_py as ce
s2 = ce.Satellite.sentinel2()
print(s2, s2.known_products())
q = ce.SearchQuery(s2).product('L2A').max_results(3)
print(q)
"

Changelog

See CHANGELOG.md for release notes.

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

copernicus_explorer-0.2.0.tar.gz (54.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

copernicus_explorer-0.2.0-cp313-cp313-win_amd64.whl (2.0 MB view details)

Uploaded CPython 3.13Windows x86-64

copernicus_explorer-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

copernicus_explorer-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

copernicus_explorer-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

copernicus_explorer-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

copernicus_explorer-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

copernicus_explorer-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

copernicus_explorer-0.2.0-cp39-cp39-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

copernicus_explorer-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

File details

Details for the file copernicus_explorer-0.2.0.tar.gz.

File metadata

  • Download URL: copernicus_explorer-0.2.0.tar.gz
  • Upload date:
  • Size: 54.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for copernicus_explorer-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a1fe9ee351563dbe168658985f8fe2800dc222262173406f36f830f8f6e7b630
MD5 5795e00a2b60d61a1bfce42c88aa1569
BLAKE2b-256 954980318ada996dedd22cd91af2f42c1acc8c59f299fddf917121bec300e4f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0.tar.gz:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 6caf39ea5e91b8d47a18b155c716b3b961479c6983cb76b36f8c61fae2f8c866
MD5 3592466affffc08dacf73f6aade3ebc4
BLAKE2b-256 299f305ed39414b04f0f5b00e80a84e3daa73219827eeb8a1be42afcbbfa7534

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp313-cp313-win_amd64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1dcae00bb7830e3b0f8ae3582168bd08a088d77e2093fe3ec65dde829bd5ef1a
MD5 d465cd33e0be261366288bdf2b2a9b3e
BLAKE2b-256 3ec65edf83dc3fa509ccaf29141657ed84dbc90f3e571bbafd176756b2f912a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d398cc5aa7d6305be9bcdb370b9bc5bb90cb0885d9999e107607528ad0cb9ccd
MD5 8a62a7863b9211b736222942050ae7c2
BLAKE2b-256 15bd99c4d9e7fe39c7f53e307888ef11126eb71f8fe00676a3f3f72c3ab7b740

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3bc5a6a20a79718df99502f8d8301e8fc4a1551743e43241bb8102fcbb5f0b5d
MD5 1f791d7b3f0e8f997127d5f51e247719
BLAKE2b-256 26062296d1350f39ac0d463fd09d87ed95f6917c33cd1c404ee938f107f15b86

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 314ce01260b9ed5f92ba8fac66f1219ae44e72d57f440264a517cd69fdb376d2
MD5 5ec4c3b7c276b8072a310ca50ea51e23
BLAKE2b-256 9d4585ffccf8f0fc60d7bb7f264e80de370ce0ef37e7f5253d8a9b4f57276659

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8f998b0af00c37e3da5161998f9c268a19313f6e648f5d70078c3b667a061716
MD5 ed608fed0982d8198191f5f4dfd43229
BLAKE2b-256 536d259bcf13f2db3759b685c457853ee38c0479186113e72767fc936aa64886

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 6ef5b9e208b6861ae1280773c02988eb6319787eb8aca21907437aedc64933b6
MD5 2add62c44fcf35bc98ea5385a971b353
BLAKE2b-256 3d9430f3f94ec14dc24f44f63bd88a276b97615856b47cbbecd9d6e7a1d10363

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9b8d52ad9f9bbae515a015b3c1eb213315757d756e5767e687d3677f2db6cfe5
MD5 9d58d00612ebba0cfe1cd4b3a495d37e
BLAKE2b-256 ec9714471715abd19e3a928fb2219d4bb72d364a23b5526713cdbf0181a624e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp39-cp39-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copernicus_explorer-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for copernicus_explorer-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fa0f60ad15d62e68a9e0193e69bfe904904851bf5fb9b71e463275eb879201dc
MD5 892bce401d23729d8a14a327b67b9bde
BLAKE2b-256 8f587fa5094da0f27f7981cf092c27997543a9d623ecdc727eb4740cd711d485

See more details on using hashes here.

Provenance

The following attestation bundles were made for copernicus_explorer-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on vlevasseur073/copernicus_explorer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page