Using boto3 to access Fresh Data Pool on Destination Earth

In this article, you will learn how to access Fresh Data Pool on Destination Earth Data Lake, using boto3 (AWS SDK for Python).

Fresh Data Pool, also known as EODATA (Earth Observation Data), includes satellite imagery and environmental data. With boto3, you can use Python to access and manage these large datasets stored in AWS S3 format.

What we are going to cover

EODATA Storage endpoint

S3 is an object storage service with which you can retrieve data over HTTPS using REST API. The default S3 endpoint address to work with EODATA on Destination Earth is:

https://eodata.data.destination-earth.eu

Prerequisites

No. 1 Access to My DataLake Services

You need access My DataLake Services. See How to create profile on My DataLake Services.

No. 2 Credentials for S3 EODATA access from My DataLake Services

See article How to obtain eodata S3 keys through My DataLake Services

No. 3 Python

You need Python installed on your virtual machine. In this article, we are using Ubuntu 22.04 as the underlying operating system. Adjust the commands if you are using something else.

Execute this command to test whether Python is already installed or not:

python3 --version

If the reply contains version number then yes, Python is installed and ready to be used:

Python 3.12.3

To install Python on Linux, see How to install Python virtualenv or virtualenvwrapper

No. 4 boto3 library installed

If you are using Python environment like virtualenv, enter the environment in which you wish to install boto3. In it, execute the following command:

pip3 install boto3

You can also install the package globally:

sudo apt install python3-boto3

How to create executable Python files for this article

Use nano

Make sure you have an editor installed to create Python files with it. For example, install nano text editor with a command such as

sudo apt install nano

To create a new file (or to edit an existing file), execute a command like this:

sudo nano boto3_eodata_browse.py

Paste the script that you want to execute (this list is below). Perform appropriate modifications to the code as instructed (like assigning values to variables). Save the file.

Once you have exited from the text editor, execute python3 command followed by the name of your script from the directory it is in. For example:

python3 boto3_eodata_browse.py

The script in file boto3_eodata_browse.py should be executed.

Note

For simplicity sake, in this article we will be executing only Python scripts from the folder that contains its file. Be sure to use a command such as cd to move focus to that folder or adjust files addresses in the scripts below.

Scripts developed in this article

Here is a list of Python scripts in this article:

boto3_eodata_browse.py

Browse the EODATA repository

boto3_eodata_browse_list.py

Listing the downloaded data by Prefix

boto3_eodata_download_single_file.py

How to download a PNG file

boto3_eodata_eof.py

Downloading .EOF file

boto3_eodata_download_single_tiff.py

Downloading a .TIFF file from EODATA repositories

boto3_eodata_safe.py

How to download a .SAFE directory

Browsing EODATA

You can use boto3 to browse the EODATA repository. This is Python code you are going to use:

boto3_eodata_browse.py

import boto3

access_key='YOUR_ACCESS_KEY'
secret_key='YOUR_SECRET_KEY'
directory='Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/'

host='https://eodata.data.destination-earth.eu'
container='DIAS'

s3=boto3.client('s3',aws_access_key_id=access_key, aws_secret_access_key=secret_key,endpoint_url=host)

print(s3.list_objects(Delimiter='/',Bucket=container,Prefix=directory,MaxKeys=30000)['CommonPrefixes'])

These are the variables used in the code:

access_key

Your access key. Obtain it by following Prerequisite No. 2.

secret_key

Your secret key. Obtain it by following Prerequisite No. 2.

directory

The directory within EODATA repository which you want to explore.

When filling in the variable directory, make sure to follow these rules:

  • Use slashes / as separators between elements of that path - directories and files

  • Do not start the path with a slash /

  • Since the element you are exploring is a directory, finish the path with a slash /

  • Start path with folder name found within the root directory of the EODATA repository (for example Sentinel-2 or Sentinel-5P)

If you want to explore the root directory of the EODATA repository, assign an empty string to variable directory:

directory=''

If you don’t have a directory which you want to explore but you want to simply test this method, you can leave the value which was assigned to variable directory in the example code from above.

host

EODATA endpoint, it is always https://eodata.data.destination-earth.eu.

container

The name of the container used.

Execute the code in file boto3_eodata_browse.py:

python3 boto3_eodata_browse.py

If you provided your access and secret keys but did not modify the variable directory, the code above will list products found in Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ directory of the EODATA repository. The output should look like this:

[
  {
    "Prefix": "Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110329_000000603113_00267_52867_0000.N1/"
  },
  {
    "Prefix": "Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110428_000000603113_00267_52867_0000.N1/"
  },
  {
    "Prefix": "Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110446_000000603113_00267_52867_0000.N1/"
  }
]

Listing the downloaded data by Prefix

This output can be described as a “list of dictionaries”. Each of those dictionaries contains a key called Prefix, providing the path to a file or directory. Instead of printing this list like above, you can loop through it to increase the legibility of the output:

boto3_eodata_browse_list.py

import boto3

access_key='YOUR_ACCESS_KEY'
secret_key='YOUR_SECRET_KEY'
directory='Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/'

host='https://eodata.data.destination-earth.eu'
container='DIAS'

s3=boto3.client('s3',aws_access_key_id=access_key, aws_secret_access_key=secret_key,endpoint_url=host)

for i in s3.list_objects(Delimiter='/',Bucket=container,Prefix=directory,MaxKeys=30000)['CommonPrefixes']:
    print(i['Prefix'])

Execute the code in file boto3_eodata_browse_list.py:

python3 boto3_eodata_browse_list.py

This time, the output should show only the paths:

Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110329_000000603113_00267_52867_0000.N1/
Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110428_000000603113_00267_52867_0000.N1/
Envisat-ASAR/ASAR/ASA_WSS_1P/2012/04/08/ASA_WSS_1PNESA20120408_110446_000000603113_00267_52867_0000.N1/

PNG files from an EODATA repository

Basic info on PNG files

png or PNG stands for Portable Network Graphics. This image format is widely used for raster graphics; it can

  • store pixel data,

  • include transparency support and

  • is known for its lossless compression.

In EODATA, files of type .png are sometimes used for displaying visual representations of processed EODATA, such as false-color images or classification results. They do not typically include geospatial metadata like .tiff or .SAFE but may be used to show EO imagery in a more accessible, compressed format.

How to download a PNG file

The script below should download a PNG file to a directory from which the script is being executed. If that directory already contains a file which has the same name as the one you are downloading, it will be overwritten without prompt for confirmation.

The code is in file:

boto3_eodata_download_single_file.py

import boto3

access_key='YOUR_ACCESS_KEY'
secret_key='YOUR_SECRET_KEY'
key='Landsat-5/TM/L1T/2011/11/16/LS05_RMPS_TM__GTC_1P_20111116T100042_20111116T100111_147386_0194_0035_4BF1/LS05_RMPS_TM__GTC_1P_20111116T100042_20111116T100111_147386_0194_0035_4BF1.BP.PNG'

host='https://eodata.data.destination-earth.eu'
container='DIAS'

s3=boto3.resource('s3',aws_access_key_id=access_key,
 aws_secret_access_key=secret_key, endpoint_url=host,)

bucket=s3.Bucket(container)

filename=key.split("/")[-1]

bucket.download_file(key, filename)

The variables are used in this piece of code is practically the same as previously. Execute with command

python3 boto3_eodata_download_single_file.py

If provided your access key and secret key but you did not change the contents of variable key, the code should download the file called

LS05_RMPS_TM__GTC_1P_20111116T100042_20111116T100111_147386_0194_0035_4BF1.BP.PNG

which is located within the root directory of product

LS05_RMPS_TM__GTC_1P_20111116T100042_20111116T100111_147386_0194_0035_4BF1

After executing the script, the output should be empty. Regardless, the downloaded file should be visible within the directory from which the script was executed. For example, this is what it will look like on Linux:

../../../../_images/access-eodata-boto3-03_creodias.png

And here is what the downloaded image looks like:

../../../../_images/LS05_RMPS_TM__GTC_1P_20111116T100042_20111116T100111_147386_0194_0035_4BF1.BP.PNG

EOF files from a EODATA repository

What is a .EOF file

eof is short for Earth Observation Format. It is a custom format used to store and share EODATA, though it’s less common than formats like .tiff or .SAFE. Commonly used in environmental and Earth sciences, both in research and commercial EODATA systems alike. May require specialized software for reading and processing.

Internally, it is a binary or structured file format that typically includes both image data and metadata about the observation; it usually stores both raw and processed data for specific types of EO sensors or projects.

Downloading .EOF file

Put the following code into file

boto3_eodata_eof.py:

import boto3
import os

session = boto3.session.Session()
s3 = boto3.resource(
    's3',
    endpoint_url='https://eodata.data.destination-earth.eu',
    aws_access_key_id="your_aws_access_key_id",
    aws_secret_access_key="your_aws_secret_access_key",
    region_name='default'
)  # generated secrets

def download(bucket, product: str, target: str = "") -> None:
    files = bucket.objects.filter(Prefix=product)
    if not list(files):
        raise FileNotFoundError(f"Could not find any files for {product}")
    for file in files:
        os.makedirs(os.path.dirname(f"{target}{file.key}"), exist_ok=True)
        if not os.path.isdir(f"{target}{file.key}"):
            bucket.download_file(file.key, f"{target}{file.key}")

# path to the product to download
download(s3.Bucket("eodata"), "Sentinel-1/AUX/AUX_RESORB/2023/10/03/S1A_OPER_AUX_RESORB_OPOD_20231003T050549_V20231003T010842_20231003T042612.EOF", "/your/path/to/python_eodata")

Be sure to replace your/path/to/ with your own directory path before running the code.

This code

  • downloads every file in bucket with provided product as prefix

  • raises FileNotFoundError if the product was not found

The arguments used are:

bucket:

boto3 Resource bucket object

product

Path to product

target

Local catalog for downloaded files. Should end with an “/”. Default current directory.

Execute with command

python3 boto3_eodata_eof.py

This particular file that is downloaded, is 507 Kbytes long and is containing some 15454 lines. Its start looks like this:

../../../../_images/eof_downloaded.png

.TIFF files in EODATA repositories

What is a .TIFF file

tiff or TIFF stands for Tagged Image File Format. It is commonly used in Earth Observation for storing satellite images. TIFF files can store geospatial metadata and large raster images, making them ideal for EODATA that require high precision.

A .tiff file consists of pixel data (images), often with associated geo-referencing data in the file header. Geospatial metadata can be stored in the GeoTIFF format (a variant of TIFF), which includes information such as the coordinate system and geo-referencing tags.

.TIFF format can store both single-band (grayscale) and multi-band (color) raster data; widely used in remote sensing applications, including vegetation mapping, land cover classification, and terrain analysis.

Downloading a .TIFF file from EODATA repositories

Put the following code into file

boto3_eodata_download_single_tiff.py

import boto3
import datetime
import os

access_key='YOUR_ACCESS_KEY'
secret_key='YOUR_SECRET_KEY'
# Host and bucket info
host = 'https://eodata.data.destination-earth.eu'
container = 'DIAS'

# TIFF file inside the .SAFE directory
key = (
    'Sentinel-1/SAR/SLC/2019/10/13/'
    'S1B_IW_SLC__1SDV_20191013T155948_20191013T160015_018459_022C6B_13A2.SAFE/'
    'measurement/s1b-iw1-slc-vh-20191013t155949-20191013t160014-018459-022c6b-001.tiff'
)

filename = key.split('/')[-1]

# Set up the S3 resource
s3 = boto3.resource(
    's3',
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    endpoint_url=host
)

bucket = s3.Bucket(container)

# Print start time
start_time = datetime.datetime.now()
print(f"Starting download at: {start_time}")

# Download the file
bucket.download_file(key, filename)

# Print end time
end_time = datetime.datetime.now()
print(f"Download finished at: {end_time}")

# Calculate duration
duration = end_time - start_time
print(f"Download duration: {duration.total_seconds()} seconds")

# Print file size in MB
file_size = os.path.getsize(filename) / (1024 * 1024)
print(f"Downloaded file: {filename}")
print(f"File size: {file_size:.2f} MB")

Execute with command

python3 boto3_eodata_download_single_tiff.py

This is the textual output of the code:

../../../../_images/downloaded-tif-with-print.png

The downloaded grayscale .TIFF file looks like:

../../../../_images/tif-downloaded-twice.png

If you are downloading .SAFE directories, all .TIFF files will be automatically included into the download.

.SAFE objects in EODATA repository

What is a .SAFE format

The .SAFE file format is a directory-based structure typically used by the European Space Agency (ESA) for its Sentinel satellite missions (e.g., Sentinel-1, Sentinel-2). It is not a single file but a directory structure containing metadata, image bands, calibration data, and other auxiliary files necessary for processing the satellite data. Because of that complexity, usually it requires specialized software like the ESA Sentinel Application Platform (SNAP) for proper viewing and processing.

The .SAFE product structure includes a directory containing a series of folders, each of which represents different product types, such as measurement data, calibration, metadata, etc.

Common files inside a .SAFE directory are:

Manifest file (manifest.safe)

Contains high-level metadata about the product.

Measurement files (e.g., .tiff, .png)

Represent the EO image data.

Metadata files (.xml)

Contain detailed information about the acquisition, including satellite orbit data, processing level, and time stamps.

How to download a .SAFE directory

Put the following code into file

boto3_eodata_safe.py:

import boto3
import os

# Your credentials and endpoint
access_key="your_aws_access_key_id"
secret_key="your_aws_secret_access_key"
endpoint = 'https://eodata.data.destination-earth.eu'

bucket_name = 'eodata'
prefix = 'Sentinel-1/SAR/SLC/2019/10/13/S1B_IW_SLC__1SDV_20191013T155948_20191013T160015_018459_022C6B_13A2.SAFE/'

# Local directory where files will be saved
local_base_dir = './downloaded_files'  # Change this to your desired folder

# Create the client
s3 = boto3.client(
    's3',
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    endpoint_url=endpoint
)


# Create the local base directory if it doesn't exist
os.makedirs(local_base_dir, exist_ok=True)

# Handle pagination
continuation_token = ''
while True:
    # List objects with pagination (max 1000 items per page)
    list_params = {
        'Bucket': bucket_name,
        'Prefix': prefix,
        'ContinuationToken': continuation_token if continuation_token else ''  # Use empty string if no continuation token
    }
    response = s3.list_objects_v2(**list_params)

    # Loop through each object
    for obj in response.get('Contents', []):
        key = obj['Key']

        # Skip directories (keys that end with "/")
        if key.endswith('/'):
            continue

        # Generate local file path, preserving folder structure
        local_path = os.path.join(local_base_dir, key)  # Save to specified folder
        local_dir = os.path.dirname(local_path)  # Extract the parent directory

        # Create parent directories if necessary
        os.makedirs(local_dir, exist_ok=True)

        # Download the file to the local path
        print(f'Downloading {key} -> {local_path}')
        s3.download_file(bucket_name, key, local_path)

    # Check if there are more files to list
    if response.get('IsTruncated'):  # More files exist, continue listing
        continuation_token = response.get('NextContinuationToken')
    else:
        break

print("✅ Download complete.")

Execute with command

python3 boto3_eodata_safe.py

Creating directories while downloading a single file

The main problem when downloading a .SAFE directory is that S3 data look like they are placed in a directory, while they are actually not. Therefore, when downloading these files, the code has to break down the file structure and translate it to directory structure needed for actual presence on Linux or Windows operating systems. To make things more complicated, if the subdirectory is not available in advance (and most of the time it won’t be), the code needs to create the relevant subdirectories on the go. In this particular case, there is a command

local_base_dir = './downloaded_files'

which defines a start of the directory and subdirectories that will be created. (It goes without saying that you could/should change this variable in case of frequent downloading of .SAFE files.)

Files downloaded from this .SAFE project

Here is the “main” directory on local disk:

../../../../_images/download_safe_first_look.png

Underneath, we get the actual files downloaded:

../../../../_images/second-safe-directory.png

File /preview/quick-look.png shows what part of Earth surface has been observed and recorded in .SAFE format:

../../../../_images/quick-look-safe-download.png

Under measurement subdirectory, we see the downloaded .TIFF files:

../../../../_images/downloaded-tiff-files.png

Note that .TIFF files are all longer than 1 GB of data.

There is also a PDF file for .SAFE product:

../../../../_images/pdf-file-downloaded.png

Eventual problems when downloading .SAFE files

.SAFE format is a compound of a possibly large number of possibly large files so that main problem is that files can become corrupted during the download. Also, the download may be incomplete or take too long, or the files cannot be downloaded because of their sheer size.

In conjunction, the download speeds may dwindle if you are downloading them from remote storage or if you are sharing bandwidth with others. The destination provider may also throttle your API access if you are making a large number requests while downloading files. Specifically, if you are using list_objects_vw from AWS S3 protocol, it will have a limit of 1000 objects per request.

The resolution of these problems is far beyond the context of this article, but we can also mention other possible causes of troubles:

  • firewall or network configuration issues,

  • timeouts,

  • invalid or missing metadata,

  • unrecognized or unsupported file formats,

  • nested directory structure handling

and so on.

What To Do Next

To access EODATA on Destination Earth, you can also use s3cmd and AWS CLI:

Using AWS CLI to access Fresh Data Pool on Destination Earth

Using s3cmd to access Fresh Data Pool on Destination Earth