Skip to main content

Clients for interacting with Copernicus Data Space Ecosystem

Project description

CDSE Downloader

Clients for searching and downloading data from Copernicus Data Space Ecosystem.

The structure of this client takes inspiration from a lot of clients I have used of the years. I designed some patterns around what I liked and found helpful and powerful in them.

TODO

  • Auth
    • create tokens
    • refresh tokens
    • s3 auth
  • OData
    • query products
    • query deleted products
    • query by list
    • query nodes
  • OpenSearch
    • Query products
  • Download products
    • download single product
    • download multiple products in parallel
    • download by id or name
  • Subscriptions
  • CLI?

Usage

OData

Product Search

To search OData use ProductSearch to query the API. Specify a collection, sensing date, publication date, area, and can further filter using lists of AttributeFilter

from cdse_dl.odata.filter import AttributeFilter
from cdse_dl.odata.search import ProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C")
]
area = "POINT (12.4577739 41.9077492)"

search = ProductSearch(
    collection="SENTINEL-2",
    area=area,
    date="2020-01-01/2020-01-02",
    filters=filters,
)
search.get(10)

To see what collection, attributes, and attribute types are available and can be used to search with, check the following example.

from cdse_dl.odata import get_attribute_type, get_collection_attributes, get_collections

# get all collections that can be searched with
collections = get_collections()

# get all attributes for a collection
attributes = get_collection_attributes("SENTINEL-1")

# get the type the attribute is expected to be
attr_type = get_attribute_type("SENTINEL-1", "sliceNumber")

OData searching allows the use of filters to build complex query patterns using OData's ability to filter on Attributes of the products. Use or_, and_ or not_ to combine or invert filters.

Any filters passed in the the list are and-ed together to build the final filter.

Filter Methods:

  • Greater then: gt
  • Less then: lt
  • Greater then or equal : gte
  • Less then or equal: lte
  • Equal to: eq
  • Not equal to: neq
  • String contains: contains
  • String starts with: startswith
  • String ends with: endswith
from cdse_dl.odata.filter import AttributeFilter, Filter
from cdse_dl.odata.search import ProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C"),
    Filter.or_([
        AttributeFilter.eq("tileId","32TPN"),
        AttributeFilter.eq("tileId","33TUH"),
    ]),
    Filter.and_([
        AttributeFilter.gt("cloudCover", 10),
        AttributeFilter.lt("cloudCover", 50),
    ]),
    AttributeFilter.eq("processorVersion","05.00").not_()
]
area = "POINT (12.4577739 41.9077492)"

search = ProductSearch(
    collection="SENTINEL-2",
    date="2020-01-01/2020-02-01",
    filters=filters,
    expand="Attributes"
)
print(search.hits())
products = search.get(20)

You can use other params such as order_by, expand, skip, and top to modify your search. skip and top are used during .get() and .get_all() and unless necessary can be ignored.

expand will add full metadata of each returned result. You can expand Attributes or Assets.

from cdse_dl.odata.filter import AttributeFilter
from cdse_dl.odata.search import ProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C")
]
area = "POINT (12.4577739 41.9077492)"

search = ProductSearch(
    collection="SENTINEL-2",
    area=area,
    date="2020-01-01/2020-01-02",
    filters=filters,
    order_by="ContentDate/Start",
    expand="Attributes"
)
search.get(1)

Deleted Product Search

To search for a specific deleted product, you can use OData's deleted product API with DeletedProductSearch.

from cdse_dl.odata.search import DeletedProductSearch

search = DeletedProductSearch(
    collection="SENTINEL-2",
    name="S2A_MSIL1C_20210331T100021_N0500_R122_T32TQM_20230218T121926.SAFE",
)
search.get(1)

To find products deleted during a specified date range, use the deletion_date filter

from cdse_dl.odata.search import DeletedProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C")
]

search = DeletedProductSearch(
    collection="SENTINEL-2",
    deletion_date="2024-01-31/2024-02-01",
    filters=filters,
)
search.hits()

To find products from published in a specified date range that have been deleted, use the origin_date filter

from cdse_dl.odata.search import DeletedProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C")
]

search = DeletedProductSearch(
    collection="SENTINEL-2",
    origin_date="2022-02-01/2022-02-10",
    filters=filters,
)
search.hits()

OpenSearch

Product Search

OData

Product Search

from cdse_dl.opensearch.search import ProductSearch

search = ProductSearch(
    collection="Sentinel2",
    point=(12.4577739,41.9077492),
    product_type="S2MSI1C",
    date="2000-01-01/2024-05-01",
)
items = list(search.get(10))

Download

To download a product, use the Downloader to manage downloading.

from cdse_dl.odata.search import ProductSearch
from cdse_dl.download import Downloader

name = "S2A_MSIL1C_20200116T100341_N0208_R122_T33TUH_20200116T103621.SAFE"

product = ProductSearch(name=name).get(1)[0]

downloader = Downloader()
downloader.download(product, "tmp")

You can auth from environment variables, netrc, or pass your own personal credentials.

from cdse_dl.download import Downloader
from cdse_dl.auth import Credentials

creds = Credentials.from_login("username", "password")
downloader = Downloader(credentials=creds)

To download multiple products, use download_all. The download manager will manage the 4 concurrent product limit of downloads on the session.

from cdse_dl.download import Downloader
from cdse_dl.odata.filter import AttributeFilter
from cdse_dl.odata.search import ProductSearch

filters = [
    AttributeFilter.eq("productType","S2MSI1C")
]

products = ProductSearch(collection="SENTINEL-2",filters=filters).get(5)

downloader = Downloader()
downloader.download_all(products, "tmp")

If you want to interact with files over the s3 api, you can do so using the s3fs session from get_s3fs_session, which authorizes you to the CDSE s3 api.

This endpoint may be higher performance from my testing.

from cdse_dl.auth import get_s3fs_session
from fsspec.callbacks import TqdmCallback

fs = get_s3fs_session()
tqdm_kwargs = {"unit":"files"}

remote_path = "eodata/Sentinel-2/MSI/L1C/2021/07/11/S2B_MSIL1C_20210711T095029_N0301_R079_T34UEC_20210711T110140.SAFE"
local_path = "S2B_MSIL1C_20210711T095029_N0301_R079_T34UEC_20210711T110140.SAFE"

_ = fs.get(
    remote_path,
    local_path,
    recursive=True,
    callback=TqdmCallback(tqdm_kwargs=tqdm_kwargs),
)

Subscriptions

Tooling to work with CDSE subscriptions endpoint, allowing creation of subscriptions, reading, acking, etc.

Example Usage:

from cdse_dl.odata.filter import AttributeFilter, Filter
from cdse_dl.subscriptions import SubscriptionClient

# Subscriptions client (with credentialed session)
client = SubscriptionClient()

# OData Filter
filter = Filter.and_([
    Filter.eq("Collection/Name", "SENTINEL-2"),
    AttributeFilter.eq("productType","S2MSI1C")
])

# create a subscription
sub = client.create_subscription(filter)
print(sub)

# list current subscriptions
subs = client.list_subscriptions()
print(subs)

# delete subscription
client.delete_subscription(sub['Id'])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cdse_dl-0.1.0a1.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cdse_dl-0.1.0a1-py3-none-any.whl (21.2 kB view details)

Uploaded Python 3

File details

Details for the file cdse_dl-0.1.0a1.tar.gz.

File metadata

  • Download URL: cdse_dl-0.1.0a1.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.5

File hashes

Hashes for cdse_dl-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 c6c3e2e90f16f05248ea3fcac23b0fff1030e335997138bec200eea7d8fe4108
MD5 274e0ebdb40201c4d7dc91e6ef9566dd
BLAKE2b-256 e7f0934c697f30d9c2563b6c9cb7ceb9b0c34eaa037dbe3c889be2a6be098f8c

See more details on using hashes here.

File details

Details for the file cdse_dl-0.1.0a1-py3-none-any.whl.

File metadata

  • Download URL: cdse_dl-0.1.0a1-py3-none-any.whl
  • Upload date:
  • Size: 21.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.5

File hashes

Hashes for cdse_dl-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 4e543ef572f022cb8fd7a19bb76b2da72a75924d3eff4755c52199752d8d6d2e
MD5 46c392a317ddfc702bc224c0b0cb5cae
BLAKE2b-256 49b6d302ca381bc0dcf5adc4d20683156d06a3fdda5999110f1f037f485971b9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page