EarthDaily Python Client
The EarthDaily Python Client is a comprehensive library for interacting with the EarthDaily Analytics platform. It provides seamless access to satellite data, STAC item management, and platform APIs through a unified interface.
EDS means Earth Data Store, the data platform behind this client. Requests go to the EarthPlatform STAC API.
🚀 Key Features
- Platform API Access: Full integration with EarthDaily platform services
- STAC Item Management: Complete CRUD operations for STAC items
- Datacube Module: Modern, self-contained datacube creation and manipulation
- Modern Architecture: Streamlined client design with comprehensive error handling
- Flexible Installation: Modular installation options for different use cases
📦 Installation
Supported Python Versions: 3.11, 3.12, 3.13, 3.14, 3.15
Basic Installation
pip install earthdaily
Recommended Installation (Platform Features)
pip install "earthdaily[platform]"
Datacube Support
pip install "earthdaily[datacube]"
Full Installation (All Features)
pip install "earthdaily[platform,datacube]"
Full Installation with utils (for .env file and Jupyter notebooks)
pip install "earthdaily[platform,datacube,utils]"
Install from a checkout
The commands above install a release with pip. From a git checkout, uv can install the client and its extras:
uv sync --extra platform --extra datacube
Looking for v1/legacy functionality? The legacy module (
client.legacy) was removed in v2.0.0. If you need legacy datacube features, pin to v1.x.x (earthdaily<2.0.0). The v1.x.x line will continue to receive security and critical bug fixes only.
Environment Setup
The EarthPlatform STAC API is protected by bearer authentication. A bearer token is generated using OAuth Client Credentials Flow. The required client_id, client_secret, and access_token_url values can be found on the Account Management Console.
Getting Your Credentials
- Go to the Account Management Console
- Click the Provision New API Credentials button to generate your API credentials
- Copy the generated
client_secretvalue — this will be yourEDS_SECRET
For more details, see the API Authentication Guide.
Configure Your Environment
Create a .env file in your project root with your credentials:
# .env
EDS_CLIENT_ID=EARTHDAILY_API_TOKEN
EDS_SECRET=<Go to Account Management Console, click Provision New API Credentials, copy the client_secret>
EDS_AUTH_URL=https://api.earthdaily.com/account_management/v1/authentication/api_tokens/exchange
EDS_API_URL=https://api.earthdaily.com
Note: To use .env files and Jupyter notebooks, install with the utils extra:
pip install "earthdaily[utils]"
🏃 Quick Start
from dotenv import load_dotenv
from earthdaily import EDSClient, EDSConfig
# Load environment variables
load_dotenv(".env")
# Initialize client
config = EDSConfig()
client = EDSClient(config)
Alternative Configuration
# Direct configuration (without .env file)
config = EDSConfig(
client_id="EARTHDAILY_API_TOKEN",
client_secret="<Go to Account Management Console, click Provision New API Credentials, copy the client_secret>",
token_url="https://api.earthdaily.com/account_management/v1/authentication/api_tokens/exchange",
base_url="https://api.earthdaily.com"
)
client = EDSClient(config)
Advanced Configuration Options
The EDSConfig class supports additional configuration options for customizing client behavior:
config = EDSConfig(
# ... authentication parameters ...
# HTTP retry configuration
max_retries=5, # Maximum retry attempts (default: 3)
retry_backoff_factor=2.0, # Exponential backoff factor (default: 1.0)
# Asset access mode
asset_access_mode="presigned-urls" # "presigned-urls", "proxy-urls", or "raw"
)
Retry Configuration
max_retries: Maximum number of retry attemptsretry_backoff_factor: Backoff factor for retry delays
Examples:
retry_backoff_factor=1.0: Delays of 1s, 2s, 4sretry_backoff_factor=0.5: Delays of 0.5s, 1s, 2sretry_backoff_factor=2.0: Delays of 2s, 4s, 8s
🍪 Proxy Asset URLs And Cookie File
When asset_access_mode="proxy-urls", assets are served through authenticated
proxy URLs. GDAL/rasterio cannot send the EDS bearer token, so the client can
fetch a short-lived asset cookie and write it to a Netscape-format file that
you pass through GDAL_HTTP_COOKIEFILE.
Enable the feature on EDSConfig and ask the client for a cookie file. You
must provide path explicitly so the credential-like file does not end up in
an unexpected location (for example, committed to a repository):
import rasterio
from earthdaily import EDSClient, EDSConfig
config = EDSConfig(
asset_access_mode="proxy-urls",
platform_cookie_enabled=True,
platform_cookie_auto_refresh=True,
)
with EDSClient(config) as client:
cookie_file = client.get_platform_cookie_file(
path="/tmp/earthdaily-platform-cookies.txt"
)
with rasterio.Env(GDAL_HTTP_COOKIEFILE=str(cookie_file)):
... # e.g. odc.stac.stac_load(...), rasterio.open(...)
platform_cookie_auto_refresh=Truestarts a background daemon thread that refreshes the cookie file in place before it expires.EDSClient.close()(called automatically by thewithstatement) stops the refresh thread and deletes the cookie file.- The parent directory of
pathmust already exist; the client never creates directories for you.
See the EarthMosaics notebook for a full example.
🌍 Core Features
Platform API Integration
Search for satellite data using STAC:
# Search for Sentinel-2 data
search_result = client.platform.pystac_client.search(
collections=["sentinel-2-l2a"],
datetime="2024-06-01T00:00:00Z/2024-08-01T00:00:00Z",
max_items=10
)
items = list(search_result.items())
STAC Item Management
Create and manage STAC items:
# Create a new STAC item
stac_item = {
"type": "Feature",
"stac_version": "1.0.0",
"id": "example-item-123",
"collection": "your-collection",
"geometry": {"type": "Point", "coordinates": [-67.7, -37.8]},
"properties": {"datetime": "2024-01-01T00:00:00Z"},
"links": [],
"assets": {}
}
client.platform.stac_item.create_item("your-collection", stac_item)
🏗️ Architecture Overview
The client is organized into main modules:
-
client.platform: Modern platform API accesspystac_client: STAC catalog searchstac_item: STAC item CRUD operationsbulk_search: Bulk search operationsbulk_insert: Bulk data insertionbulk_delete: Bulk data deletion
-
client.datacube: Datacube creation and manipulationcreate(): Create analysis-ready datacubes from STAC items- Masking, temporal aggregation, spectral indices, zonal statistics, and more
🔧 Platform API Methods
STAC Item Management (client.platform.stac_item)
Create Items
# Create a new STAC item
item = client.platform.stac_item.create_item(
collection_id="your-collection",
item_data={
"type": "Feature",
"stac_version": "1.0.0",
"id": "item-123",
"geometry": {"type": "Point", "coordinates": [-67.7, -37.8]},
"properties": {"datetime": "2024-01-01T00:00:00Z"}
},
return_format="dict" # "dict", "json", or "pystac"
)
Read Items
# Get a specific item
item = client.platform.stac_item.get_item(
collection_id="your-collection",
item_id="item-123",
return_format="pystac"
)
Update Items
# Update an existing item
updated_item = client.platform.stac_item.update_item(
collection_id="your-collection",
item_id="item-123",
item_data={"properties": {"updated": "2024-01-02T00:00:00Z"}},
return_format="dict"
)
Delete Items
# Delete an item
client.platform.stac_item.delete_item(
collection_id="your-collection",
item_id="item-123"
)
Download Assets
# Download item assets
downloads = client.platform.stac_item.download_assets(
item=item,
asset_keys=["blue", "green", "red"],
output_dir="./downloads",
max_workers=3
)
Bulk Search (client.platform.bulk_search)
Create Bulk Search
# Create a bulk search job
search_job = client.platform.bulk_search.create(
collections=["sentinel-2-l2a"],
datetime="2024-01-01T00:00:00Z/2024-02-01T00:00:00Z",
bbox=[-74.2, 40.6, -73.9, 40.9], # NYC area
limit=1000,
export_format="stacjson"
)
print(f"Job ID: {search_job.job_id}")
Monitor Job Status
# Check job status
job_status = client.platform.bulk_search.fetch(search_job.job_id)
print(f"Status: {job_status.status}")
print(f"Assets: {len(job_status.assets)}")
Download Results
# Download search results when completed
if job_status.status == "COMPLETED":
job_status.download_assets(save_location=Path("./bulk_results"))
Bulk Insert (client.platform.bulk_insert)
Create Bulk Insert Job
# Create bulk insert job
insert_job = client.platform.bulk_insert.create(
collection_id="your-collection",
error_handling_mode="CONTINUE", # or "STOP"
conflict_resolution_mode="SKIP" # or "OVERRIDE"
)
Upload Data
# Prepare a directory of STAC items, one folder per item, each containing a
# matching <item_id>.json file (plus any local assets to upload):
# stac_items/
# item-1/
# item-1.json
# item-2/
# item-2.json
items_dir = Path("./stac_items")
# Zip the directory into the bundle expected by the platform, then upload it
bundle = client.platform.bulk_insert.zip_dir(items_dir)
insert_job.upload(bundle)
# Start the job
insert_job.start()
Monitor Insert Progress
# Check insert job status
job_status = client.platform.bulk_insert.fetch(insert_job.job_id)
print(f"Items written: {job_status.items_written_count}")
print(f"Errors: {job_status.items_error_count}")
Bulk Delete (client.platform.bulk_delete)
Create Bulk Delete Job
# Create bulk delete job
delete_job = client.platform.bulk_delete.create(
collection_id="your-collection"
)
Upload Item IDs
# Prepare a JSON file containing a list of item IDs to delete.
# It must be a JSON array of unique strings, e.g.: ["item-1", "item-2", "item-3"]
ids = ["item-1", "item-2", "item-3"]
ids_file = Path("./items_to_delete.json")
ids_file.write_text(json.dumps(ids))
delete_job.upload(ids_file)
# Start the deletion
delete_job.start()
Monitor Deletion Progress
# Check delete job status
job_status = client.platform.bulk_delete.fetch(delete_job.job_id)
print(f"Items deleted: {job_status.items_deleted_count}")
print(f"Errors: {job_status.items_error_count}")
STAC Catalog Search (client.platform.pystac_client)
Standard STAC Search
# Search for items using STAC API
search_results = client.platform.pystac_client.search(
collections=["sentinel-2-l2a"],
datetime="2024-01-01T00:00:00Z/2024-02-01T00:00:00Z",
bbox=[-74.2, 40.6, -73.9, 40.9],
max_items=50
)
# Process results
items = list(search_results.items())
print(f"Found {len(items)} items")
Get Collections
# List available collections
collections = client.platform.pystac_client.get_collections()
for collection in collections:
print(f"Collection: {collection.id}")
🔍 Usage Examples
Data Discovery
# Find available collections
collections = client.platform.pystac_client.get_collections()
print([c.id for c in collections])
Download Data
# Download assets from search results
for item in items:
client.platform.stac_item.download_assets(
item,
asset_keys=["blue", "green", "red"],
output_dir="./downloads",
max_workers=3
)
📚 Documentation & Examples
- 📖 Earth Data Store (EDS) documentation
- 📖 EarthDaily Python Client documentation
- 📝 Quick Start Examples
- 🧪 Jupyter Notebooks
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details on:
- Development setup
- Code style guidelines
- Testing procedures
- Pull request process
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🆘 Support
Need help? Here's how to get support:
- 📖 Check the documentation
- 🐛 Open an issue for bugs
- 💬 Ask questions in GitHub Discussions
Ready to get started? Check out our Quick Start Example or explore the API Documentation! 🚀
Metadata
Release files for earthdaily 2.1.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 | |
|---|---|---|---|
| earthdaily-2.1.0.tar.gz | 9.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| earthdaily-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.2 MB
Release files / earthdaily-2.1.0.tar.gz
| Download URL | earthdaily-2.1.0.tar.gz |
|---|---|
| Size | 9.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d3ac93b46678a07f196fb4613843d5e13a99de693262ac12fb13a808ea62ec30
|
|
BLAKE2b-256 checksum How to use checksums |
3f3d461840e5c3ea8f99afc1a4791198a6546ffac1e689b573e085705a8b0885
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Oct 14, 2026.
Transparency logRelease files / earthdaily-2.1.0-py3-none-any.whl
| Download URL | earthdaily-2.1.0-py3-none-any.whl |
|---|---|
| Size | 97.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
36c832c890c685beb8400734f55e3bebced2efd43489e90bddf4353628ea790f
|
|
BLAKE2b-256 checksum How to use checksums |
15db9ccc48daf0943a6f672df6ed4e2e9f7c6f16fe11cfb388954a8b58b8a8c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Oct 14, 2026.
Transparency log