Skip to main content

EarthDaily Python Client

PyPI version Documentation Python Versions

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
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

  1. Go to the Account Management Console
  2. Click the Provision New API Credentials button to generate your API credentials
  3. Copy the generated client_secret value — this will be your EDS_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 attempts
  • retry_backoff_factor: Backoff factor for retry delays

Examples:

  • retry_backoff_factor=1.0: Delays of 1s, 2s, 4s
  • retry_backoff_factor=0.5: Delays of 0.5s, 1s, 2s
  • retry_backoff_factor=2.0: Delays of 2s, 4s, 8s

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=True starts a background daemon thread that refreshes the cookie file in place before it expires.
  • EDSClient.close() (called automatically by the with statement) stops the refresh thread and deletes the cookie file.
  • The parent directory of path must 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 access

    • pystac_client: STAC catalog search
    • stac_item: STAC item CRUD operations
    • bulk_search: Bulk search operations
    • bulk_insert: Bulk data insertion
    • bulk_delete: Bulk data deletion
  • client.datacube: Datacube creation and manipulation

    • create(): 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
)
# 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)

# 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

🤝 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:


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)

Source distribution for earthdaily 2.1.0
File Size Uploaded
earthdaily-2.1.0.tar.gz 9.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for earthdaily 2.1.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

2.0.0

2 release files

1.8.0

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.0.7

2 release files

1.0.0

2 release files

0.5.9

1 release file

0.5.8

1 release file

0.5.7

1 release file

0.5.6

1 release file

0.5.5

1 release file

0.5.4

1 release file

0.5.3

1 release file

0.5.2

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.4

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.15

1 release file

0.2.14

1 release file

0.2.13

1 release file

0.2.12

1 release file

0.2.11

1 release file

0.2.10

1 release file

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

0.0.17

1 release file

0.0.16

1 release file

0.0.15

1 release file

0.0.14

1 release file

0.0.13

1 release file

0.0.12

1 release file

0.0.11

1 release file

0.0.10

1 release file

0.0.9

1 release file

0.0.8

1 release file

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.3

1 release file

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page