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.
- Platform API Access: Full integration with EarthDaily platform services
- STAC Item Management: Complete CRUD operations for STAC items
- Legacy Support: Backward compatibility with v0 datacube functionality
- Modern Architecture: Streamlined client design with comprehensive error handling
- Flexible Installation: Modular installation options for different use cases
Supported Python Versions: 3.10, 3.11, 3.12, 3.13
pip install earthdailypip install "earthdaily[platform]"pip install "earthdaily[legacy]"pip install "earthdaily[platform,legacy]"Create a .env file in your project root with your credentials:
# .env
EDS_CLIENT_ID=your_client_id
EDS_SECRET=your_client_secret
EDS_AUTH_URL=https://your-auth-url.com/oauth/token
EDS_API_URL=https://api.earthdaily.comNote: To use .env files, install python-dotenv separately:
pip install python-dotenvfrom dotenv import load_dotenv # pip install python-dotenv
from earthdaily import EDSClient, EDSConfig
# Load environment variables
load_dotenv(".env")
# Initialize client
config = EDSConfig()
client = EDSClient(config)# Direct configuration (without .env file)
config = EDSConfig(
client_id="EARTHDAILY_API_TOKEN",
client_secret="your_client_secret",
token_url="https://api.earthdaily.com/account_management/v1/authentication/api_tokens/exchange",
base_url="https://api.earthdaily.com"
)
client = EDSClient(config)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"
)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
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())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)Access v0 functionality through the legacy interface:
from earthdaily.legacy.datasets import load_pivot
# Load geometry and create datacube
geometry = load_pivot()
datacube = client.legacy.datacube(
"sentinel-2-l2a",
assets=["blue", "green", "red", "nir"],
intersects=geometry,
datetime=["2022-08-01", "2022-08-09"],
mask_with="native"
)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.legacy: v0 compatibility layerdatacube(): Create analysis-ready datacubessearch(): Legacy search functionality- Access to existing v0 methods
# 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"
)# Get a specific item
item = client.platform.stac_item.get_item(
collection_id="your-collection",
item_id="item-123",
return_format="pystac"
)# 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 an item
client.platform.stac_item.delete_item(
collection_id="your-collection",
item_id="item-123"
)# Download item assets
downloads = client.platform.stac_item.download_assets(
item=item,
asset_keys=["blue", "green", "red"],
output_dir="./downloads",
max_workers=3
)# 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}")# 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 search results when completed
if job_status.status == "COMPLETED":
job_status.download_assets(save_location=Path("./bulk_results"))# 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"
)# Prepare STAC items file and upload
items_file = Path("./stac_items.jsonl") # JSONL format
insert_job.upload(items_file)
# Start the job
insert_job.start()# 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}")# Create bulk delete job
delete_job = client.platform.bulk_delete.create(
collection_id="your-collection"
)# Prepare file with item IDs to delete
ids_file = Path("./items_to_delete.txt")
delete_job.upload(ids_file)
# Start the deletion
delete_job.start()# 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}")# 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")# List available collections
collections = client.platform.pystac_client.get_collections()
for collection in collections:
print(f"Collection: {collection.id}")from earthdaily.legacy.datasets import load_pivot
# Load sample geometry
geometry = load_pivot()
# Create analysis-ready datacube
datacube = client.legacy.datacube(
collections="sentinel-2-l2a",
assets=["blue", "green", "red", "nir"],
intersects=geometry,
datetime=["2022-08-01", "2022-08-09"],
mask_with="native", # Apply cloud masking
clear_cover=50, # Minimum 50% clear pixels
groupby_date="mean" # Aggregate by date
)# Search for items (legacy interface)
items = client.legacy.search(
collections="sentinel-2-l2a",
intersects=geometry,
datetime=["2022-08-01", "2022-08-09"],
limit=100
)
print(f"Found {len(items)} items")# Create datacube from multiple collections
datacube = client.legacy.datacube(
collections=["sentinel-2-l2a", "landsat-c2l2-sr"],
assets=["red", "green", "blue"],
intersects=geometry,
datetime="2022-08",
cross_calibration_collection="landsat-c2l2-sr"
)# Find available collections
collections = client.platform.pystac_client.get_collections()
print([c.id for c in collections])# 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
)- π EDA Documentation
- π Full API Documentation
- π Migration Guide (v0 β v1)
- π Quick Start Examples
- π§ͺ Jupyter Notebooks
We welcome contributions! Please see our Contributing Guide for details on:
- Development setup
- Code style guidelines
- Testing procedures
- Pull request process
This project is licensed under the MIT License - see the LICENSE file for details.
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! π