Python client for Copernicus Data Space Ecosystem (CDSE) - Drop-in replacement for sentinelsat
Project description
cdse-client
Python client for Copernicus Data Space Ecosystem (CDSE) — a modern replacement for workflows previously built around sentinelsat.
sentinelsat was built for DHuS/SciHub (now closed) and is archived; it does not support CDSE downloads. cdse-client targets CDSE's APIs (STAC for search, OData/Zipper for downloads).
Highlights:
- Search products via STAC
- Download products via OData/Zipper (with progress bars)
- Optional extras for geocoding/GeoPandas, async downloads, and raster processing
- Type hints (PEP 561 /
py.typed)
Compatibility: Python >= 3.9
Why cdse-client?
| Feature | sentinelsat | cdse-client |
|---|---|---|
| Works with CDSE downloads | No | Yes |
| Async downloads | No | Optional (cdse-client[async]) |
| Built-in processing helpers | No | Optional (cdse-client[processing]) |
| City name search | No | Optional (cdse-client[geo]) |
| Type hints | Partial | Yes |
| Maintenance status | Archived | Active |
Installation
pip install cdse-client # Core
pip install cdse-client[geo] # + shapely, geopandas, geopy
pip install cdse-client[dataframe] # + pandas
pip install cdse-client[processing] # + rasterio, numpy, pillow, matplotlib, shapely
pip install cdse-client[async] # + aiohttp, aiofiles
pip install cdse-client[all] # Everything
Setup
- Register at Copernicus Data Space
- Create OAuth2 credentials in Account Settings
- Configure credentials using one of the methods below:
Option A: Environment variables (recommended for production)
macOS/Linux (bash/zsh)
export CDSE_CLIENT_ID="your-client-id"
export CDSE_CLIENT_SECRET="your-client-secret"
Windows (PowerShell)
$env:CDSE_CLIENT_ID = "your-client-id"
$env:CDSE_CLIENT_SECRET = "your-client-secret"
Option B: .env file (recommended for development)
Copy the example file and fill in your credentials:
cp .env.example .env
# Edit .env with your credentials
The .env file format:
CDSE_CLIENT_ID=your-client-id
CDSE_CLIENT_SECRET=your-client-secret
Note: The
.envfile is automatically ignored by git. Never commit credentials.
Features
- Smart search: STAC API with time range, bbox/geometry, cloud cover
- Downloads: OData/Zipper with progress bars, checksums, quicklooks
- Export: DataFrame / GeoJSON / GeoDataFrame
- Optional extras: geocoding, async downloads, raster processing utilities
- CLI: search/download/collections
Quick start
Basic Search & Download
from cdse import CDSEClient
client = CDSEClient(output_dir="./downloads") # Uses CDSE_CLIENT_ID and CDSE_CLIENT_SECRET
# Search Sentinel-2 products over Milan
products = client.search(
bbox=[9.0, 45.0, 9.5, 45.5],
start_date="2024-01-01",
end_date="2024-01-31",
collection="sentinel-2-l2a",
cloud_cover_max=20,
limit=5
)
# Download all results
for product in products:
client.download(product)
Search by City Name
from cdse import CDSEClient, bbox_from_city
client = CDSEClient()
# Get bounding box for any city
bbox = bbox_from_city("Paris, France")
products = client.search(
bbox=bbox,
start_date="2024-06-01",
end_date="2024-06-30",
collection="sentinel-2-l2a"
)
Async Downloads
import asyncio
from cdse import CDSEClientAsync
async def main():
async with CDSEClientAsync(output_dir="./downloads", max_concurrent=3) as client:
products = await client.search(
bbox=[9.0, 45.0, 9.5, 45.5],
start_date="2024-01-01",
end_date="2024-01-31",
collection="sentinel-2-l2a",
limit=10,
)
await client.download_all(products)
asyncio.run(main())
For raster processing examples (NDVI, band extraction, previews), see the Processing section below.
Search methods
# By bounding box
products = client.search(bbox=[lon_min, lat_min, lon_max, lat_max], ...)
# By geographic point
products = client.search_by_point(lon=9.19, lat=45.46, buffer_km=10, ...)
# By city name (requires [geo])
products = client.search_by_city(city_name="Milano, Italia", ...)
# By product name (OData catalogue)
products = client.search_by_name("S2A_MSIL2A_20240115T102351...", exact=True)
# By UUID (OData catalogue)
product = client.search_by_id("a1b2c3d4-e5f6...")
Note: search() returns STAC results; product identifiers there are not guaranteed to be OData UUIDs. If you need a UUID, use search_by_name(..., exact=True).
Collections: sentinel-1-grd, sentinel-2-l1c, sentinel-2-l2a, sentinel-3-olci, sentinel-3-slstr, sentinel-5p-l2
Download methods
# Single product
client.download(product, output_dir="./downloads")
# Multiple products (parallel)
client.download_all(products, parallel=True, max_workers=4)
# With checksum verification
client.download_with_checksum(product)
# Quicklook preview only
client.download_quicklook(product)
client.download_all_quicklooks(products)
Data export (sentinelsat compatible)
# DataFrame for sorting/filtering
df = client.to_dataframe(products)
df.sort_values('cloud_cover').to_csv("products.csv")
# GeoJSON footprints
geojson = client.to_geojson(products)
# GeoDataFrame for spatial analysis (requires [geo])
gdf = client.to_geodataframe(products)
gdf.plot()
# Total size
size_gb = client.get_products_size(products)
Geometry utilities
from cdse import read_geojson, geojson_to_wkt, bbox_to_geojson
geojson = read_geojson("area.geojson")
wkt = geojson_to_wkt(geojson)
geojson = bbox_to_geojson([9.0, 45.0, 9.5, 45.5])
Processing (optional)
Install:
pip install cdse-client[processing]
Example:
from cdse.processing import calculate_ndvi, crop_and_stack, preview_product
# Extract bands, crop to AOI, stack into a GeoTIFF
stack_path = crop_and_stack(
safe_path="S2A_MSIL2A_20240115.zip",
bbox=[9.15, 45.45, 9.25, 45.55],
bands=["B04", "B03", "B02", "B08"],
resolution=10,
)
# NDVI from band files
ndvi = calculate_ndvi(nir_path="B08.tif", red_path="B04.tif")
# Quick preview (writes a PNG)
preview_product(safe_path="S2A_MSIL2A_20240115.zip", output_path="preview.png")
Async (optional)
Install:
pip install cdse-client[async]
Example:
import asyncio
from cdse import CDSEClientAsync
async def main() -> None:
async with CDSEClientAsync(output_dir="./downloads", max_concurrent=3) as client:
products = await client.search(
bbox=[9.0, 45.0, 9.5, 45.5],
start_date="2024-01-01",
end_date="2024-01-31",
collection="sentinel-2-l2a",
cloud_cover_max=20,
limit=3,
)
# WARNING: downloads can be large
# paths = await client.download_all(products)
asyncio.run(main())
CLI
cdse --help
cdse collections
# Search
cdse search --bbox 9.0,45.0,9.5,45.5 -s 2024-01-01 -e 2024-01-31 -c 20 -l 5
# Download by name/UUID
cdse download --name S2A_MSIL2A_20240115T102351...
cdse download --uuid a1b2c3d4-e5f6-... --checksum
cdse download --uuid a1b2c3d4-e5f6-... --quicklook
Documentation
- Site: https://vtvito.github.io/cdse-client/
- Migration guide: https://vtvito.github.io/cdse-client/migration/
- Examples: examples/
Migration from sentinelsat
| sentinelsat | cdse-client |
|---|---|
SentinelAPI(user, password) |
CDSEClient(client_id, client_secret) (OAuth2) |
api.query(...) |
client.search(...) |
api.download(...) |
client.download(product) |
api.download_all(...) |
client.download_all(products) |
api.to_dataframe(...) |
client.to_dataframe(products) |
api.to_geojson(...) |
client.to_geojson(products) |
api.to_geodataframe(...) |
client.to_geodataframe(products) |
Contributing
Contributions welcome. See:
- CONTRIBUTING.md
- Issues: https://github.com/VTvito/cdse-client/issues
- Discussions: https://github.com/VTvito/cdse-client/discussions
Support & Community
- Bug reports: https://github.com/VTvito/cdse-client/issues
- Questions/ideas: https://github.com/VTvito/cdse-client/discussions
- Documentation: https://vtvito.github.io/cdse-client/
Resources
- Copernicus Data Space Ecosystem: https://dataspace.copernicus.eu/
- CDSE API documentation: https://documentation.dataspace.copernicus.eu/
- STAC browser: https://dataspace.copernicus.eu/browser/
Disclaimer
This is an unofficial client library and is not affiliated with, endorsed by, or connected to ESA, the European Commission, or the Copernicus Programme.
Copernicus Data Space Ecosystem and Sentinel data are provided by ESA and the European Commission. Users must:
- Register at dataspace.copernicus.eu
- Comply with the Terms and Conditions
- Respect API quotas and fair usage policies
Sentinel data is available under a free, full, and open data policy for any use, including commercial. See the Sentinel Data Legal Notice.
License
MIT License - see 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdse_client-0.3.3.tar.gz.
File metadata
- Download URL: cdse_client-0.3.3.tar.gz
- Upload date:
- Size: 54.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0608104ec758a0c278c0bf5796af23963e6b9e8a8ace2b8aa15fbd73a69bce89
|
|
| MD5 |
36376feba3cccd545365acc776fcc688
|
|
| BLAKE2b-256 |
e438522b899db3636f51191782491b7ea8ef44feda56276b16a481982dc33908
|
Provenance
The following attestation bundles were made for cdse_client-0.3.3.tar.gz:
Publisher:
publish.yml on VTvito/cdse-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdse_client-0.3.3.tar.gz -
Subject digest:
0608104ec758a0c278c0bf5796af23963e6b9e8a8ace2b8aa15fbd73a69bce89 - Sigstore transparency entry: 814731110
- Sigstore integration time:
-
Permalink:
VTvito/cdse-client@a9101dc00ce29d2fd5f1cb902d29c0065c5b8341 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/VTvito
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9101dc00ce29d2fd5f1cb902d29c0065c5b8341 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cdse_client-0.3.3-py3-none-any.whl.
File metadata
- Download URL: cdse_client-0.3.3-py3-none-any.whl
- Upload date:
- Size: 45.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6f05edac495fc7b2e5c61fa9df7c6f72e835bd809b22dfd97ac2faef77ca0df
|
|
| MD5 |
bcb0a34cd9611a38bf248699d2add8aa
|
|
| BLAKE2b-256 |
f0e0319f093a51d7cbbfe0d8bd147129e26c50c3d53668b315a8cfaf91e887ec
|
Provenance
The following attestation bundles were made for cdse_client-0.3.3-py3-none-any.whl:
Publisher:
publish.yml on VTvito/cdse-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdse_client-0.3.3-py3-none-any.whl -
Subject digest:
b6f05edac495fc7b2e5c61fa9df7c6f72e835bd809b22dfd97ac2faef77ca0df - Sigstore transparency entry: 814731111
- Sigstore integration time:
-
Permalink:
VTvito/cdse-client@a9101dc00ce29d2fd5f1cb902d29c0065c5b8341 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/VTvito
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9101dc00ce29d2fd5f1cb902d29c0065c5b8341 -
Trigger Event:
push
-
Statement type: