Skip to content

OData API (Copernicus)

Overview

The sat_download.api.odata module provides the SatelliteAPI implementation for the Copernicus Data Space Ecosystem, allowing searching and downloading of Sentinel-2 and Sentinel-3 images.


API Reference

ODataAPI

ODataAPI(username: str, password: str)

Bases: SatelliteAPI

Implementation of SatelliteAPI for the Copernicus Data Space Ecosystem OData API.

This class provides methods to search and download satellite imagery from the Copernicus Data Space Ecosystem using their OData API.

Parameters:

Name Type Description Default
username str

Username for authentication with the Copernicus Data Space API

required
password str

Password for authentication with the Copernicus Data Space API

required

Attributes:

Name Type Description
SEARCH_URL str

Endpoint URL for searching satellite products

DOWNLOAD_URL str

Endpoint URL for downloading satellite products

TOKEN_URL str

Endpoint URL for obtaining authentication tokens

Notes

Authentication is performed using Keycloak OAuth2 tokens which are obtained as needed for download operations.

See Also

sat_download.api.base.SatelliteAPI : Base class defining the API interface sat_download.api.usgs.USGSAPI : Implementation for USGS Earth Explorer API

Source code in sat_download\api\odata.py
def __init__(self, username : str, password : str) -> None:
    super().__init__(username, password)

Functions

search

search(filters: SearchFilters) -> SearchResults

Search for satellite imagery using specified filters.

Parameters:

Name Type Description Default
filters SearchFilters

The search filters to apply to the search

required

Returns:

Type Description
SearchResults

Dictionary mapping product IDs to SatelliteImage objects

Raises:

Type Description
Exception

If the API request fails

Notes

Implementation of the abstract search method for the Copernicus Data Space API.

Source code in sat_download\api\odata.py
def search(self, filters : SearchFilters) -> SearchResults:
    """
    Search for satellite imagery using specified filters.

    Parameters
    ----------
    filters : SearchFilters
        The search filters to apply to the search

    Returns
    -------
    SearchResults
        Dictionary mapping product IDs to SatelliteImage objects

    Raises
    ------
    Exception
        If the API request fails

    Notes
    -----
    Implementation of the abstract search method for the Copernicus Data Space API.
    """
    query = self.__prepare_query(filters)

    response = requests.get(self.SEARCH_URL, params = query)
    if response.status_code == 200:
        return self.__prepare_search_results(filters.collection, response.json()['value'])
    else:
        raise Exception(f"Error en la solicitud: {response.status_code}")

download

download(
    image_id: str, outname: str, verbose: int
) -> str | None

Download a satellite image by its ID.

Parameters:

Name Type Description Default
image_id str

The unique identifier of the image to download.

required
outname str

The output filename where the image will be saved.

required
verbose int

Verbosity level for logging the download process. 0 = silent, >0 = progress bar,

required

Returns:

Type Description
str | None

The file path of the downloaded image if the download is successful. Returns None if the download fails.

Raises:

Type Description
Exception

If the download fails due to an API error or network issue.

Notes
  • This method implements the abstract download method for the Copernicus Data Space API.
  • It uses OAuth2 authentication to obtain a token before initiating the download.
  • A progress bar is displayed using tqdm to indicate the download progress.
  • The method writes the downloaded file in chunks to avoid memory issues with large files.
  • Exceptions are raised for HTTP errors or other failures during the download process.
Source code in sat_download\api\odata.py
def download(self, image_id: str, outname: str, verbose : int) -> str | None:
    """
    Download a satellite image by its ID.

    Parameters
    ----------
    image_id : str
        The unique identifier of the image to download.
    outname : str
        The output filename where the image will be saved.
    verbose : int
        Verbosity level for logging the download process. 0 = silent, >0 = progress bar,

    Returns
    -------
    str | None
        The file path of the downloaded image if the download is successful.
        Returns None if the download fails.

    Raises
    ------
    Exception
        If the download fails due to an API error or network issue.

    Notes
    -----
    - This method implements the abstract `download` method for the Copernicus Data Space API.
    - It uses OAuth2 authentication to obtain a token before initiating the download.
    - A progress bar is displayed using `tqdm` to indicate the download progress.
    - The method writes the downloaded file in chunks to avoid memory issues with large files.
    - Exceptions are raised for HTTP errors or other failures during the download process.
    """
    MB = (1024 * 1024)

    keycloak_token = self.__get_token()
    session = requests.Session()
    session.headers.update({'Authorization': f'Bearer {keycloak_token}'})

    url = f"{self.DOWNLOAD_URL}({image_id})/$value"
    response = session.get(url, stream = True, verify = True, allow_redirects = True)

    if response.status_code == 200:
        total_size = int(response.headers.get('Content-Length', 0)) // MB
        with open(outname, "wb") as file:
            if verbose == 0:
                for chunk in response.iter_content(chunk_size = MB):
                    file.write(chunk)
            else:
                for chunk in tqdm(response.iter_content(chunk_size = MB), total = total_size,
                                unit = 'MB', desc = f"Downloading image at {os.path.basename(outname)}"):
                    file.write(chunk)

        return outname
    else:
        raise Exception(f"Error en la descarga: {response.status_code}")

Endpoints

Constant Value Description
SEARCH_URL https://catalogue.dataspace.copernicus.eu/odata/v1/Products Catalog search endpoint
DOWNLOAD_URL https://download.dataspace.copernicus.eu/odata/v1/Products Download endpoint
TOKEN_URL https://identity.dataspace.copernicus.eu/.../token OAuth2 token endpoint

Supported Filters

Filter Type Description Example
collection str Satellite collection "SENTINEL-2"
start_date str Start date (YYYY-MM-DD) "2024-01-01"
end_date str End date (YYYY-MM-DD) "2024-01-31"
processing_level str Processing level "L2A"
geometry str WKT geometry "POINT(-3.7 40.4)"
tile_id str Tile identifier "30TWM"
contains List[str] Strings in name ["MSIL2A"]

Usage Examples

from sat_download.api.odata import ODataAPI
from sat_download.data_types.search import SearchFilters
from sat_download.enums import COLLECTIONS

api = ODataAPI(
    username="your_email@example.com",
    password="your_secure_password"
)

filters = SearchFilters(
    collection=COLLECTIONS.SENTINEL_2.value,
    processing_level="L2A",
    start_date="2024-06-01",
    end_date="2024-06-30",
    tile_id="30TWM"
)

results = api.search(filters)

for product_id, image in results.items():
    print(f"{image.date}: {image.filename}")

Search by Geometry

# Search by point (Madrid, Spain)
filters = SearchFilters(
    collection=COLLECTIONS.SENTINEL_2.value,
    start_date="2024-01-01",
    end_date="2024-01-31",
    geometry="POINT(-3.7037902 40.4167754)"
)

results = api.search(filters)

Search with Polygon

# Search in rectangular area
wkt = "POLYGON((-4 40, -3 40, -3 41, -4 41, -4 40))"

filters = SearchFilters(
    collection=COLLECTIONS.SENTINEL_3.value,
    start_date="2024-01-01",
    end_date="2024-01-31",
    geometry=wkt
)

results = api.search(filters)

Download Images

# Search for images
results = api.search(filters)

# Download the first image
if results:
    first_id = list(results.keys())[0]
    first_image = results[first_id]

    filepath = api.download(
        image_id=first_id,
        outname=f"./images/{first_image.filename}",
        verbose=1
    )

    if filepath:
        print(f"Downloaded: {filepath}")

Authentication

ODataAPI uses OAuth2 authentication with Copernicus Keycloak:

  1. Credentials are stored during initialization
  2. Token is requested on-demand when downloading
  3. Token is refreshed automatically if expired

Account Required

Register at https://dataspace.copernicus.eu/


OData Query Syntax

The search method builds OData queries automatically:

$filter=Collection/Name eq 'SENTINEL-2' 
    and ContentDate/Start gt 2024-01-01T00:00:00.000Z
    and ContentDate/Start lt 2024-01-31T23:59:59.999Z
    and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' 
        and att/OData.CSC.StringAttribute/Value eq 'S2MSI2A')

References