Python API

Quickstart

# connect to the API
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
from datetime import date

api = SentinelAPI('user', 'password', 'https://scihub.copernicus.eu/dhus')

# download single scene by known product id
api.download(<product_id>)

# search by polygon, time, and SciHub query keywords
footprint = geojson_to_wkt(read_geojson('map.geojson'))
products = api.query(footprint,
                     date=('20151219', date(2015, 12, 29)),
                     platformname='Sentinel-2',
                     cloudcoverpercentage=(0, 30))

# download all results from the search
api.download_all(products)

# GeoJSON FeatureCollection containing footprints and metadata of the scenes
api.to_geojson(products)

# GeoPandas GeoDataFrame with the metadata of the scenes and the footprints as geometries
api.to_geodataframe(products)

# Get basic information about the product: its title, file size, MD5 sum, date, footprint and
# its download url
api.get_product_odata(<product_id>)

# Get the product's full metadata available on the server
api.get_product_odata(<product_id>, full=True)

Valid search query keywords can be found at the Copernicus Open Access Hub documentation.

Sorting & Filtering

In addition to the search query keywords sentinelsat allows filtering and sorting of search results before download. To simplify these operations sentinelsat offers the convenience functions to_geojson(), to_dataframe() and to_geodataframe() which return the search results as a GeoJSON object, Pandas DataFrame or a GeoPandas GeoDataFrame, respectively. to_dataframe() and to_geodataframe() require pandas and geopandas to be installed, respectively.

In this example we query Sentinel-2 scenes over a location and convert the query results to a Pandas DataFrame. The DataFrame is then sorted by cloud cover and ingestion date. We limit the query to first 5 results within our timespan and download them, starting with the least cloudy scene. Filtering can be done with all data types, as long as you pass the id to the download function.

# connect to the API
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
from datetime import date

api = SentinelAPI('user', 'password', 'https://scihub.copernicus.eu/dhus')

# search by polygon, time, and SciHub query keywords
footprint = geojson_to_wkt(read_geojson('map.geojson'))
products = api.query(footprint,
                     date=('20151219', date(2015, 12, 29)),
                     platformname='Sentinel-2')

# convert to Pandas DataFrame
products_df = api.to_dataframe(products)

# sort and limit to first 5 sorted products
products_df_sorted = products_df.sort_values(['cloudcoverpercentage', 'ingestiondate'], ascending=[True, True])
products_df_sorted = products_df_sorted.head(5)

# download sorted and reduced products
api.download_all(products_df_sorted['id'])

Getting Product Metadata

Sentinelsat provides two methods for retrieving product metadata from the server, one for each API offered by the Copernicus Open Access Hub:

  • query() for OpenSearch (Solr), which supports filtering products by their attributes and returns metadata for all matched products at once.
  • get_product_odata() for OData, which can be queried one product at a time but provides the full metadata available for each product, as well as information about the product file such as the file size and checksum, which are not available from OpenSearch.

Both methods return a dictionary containing the metadata items. More specifically, query() returns a dictionary with an entry for each returned product with its ID as the key and the attributes’ dictionary as the value.

All of the attributes returned by the OpenSearch API have a corresponding but differently named attribute in the OData’s full metadata response. See the DataHubSystem’s metadata definition files to find the exact mapping between them (OpenSearch attributes have a <solrField> tag added): - Sentinel-1 attributes - Sentinel-2 attributes - Sentinel-3 attributes

OpenSearch example

>>> api.query(date=('NOW-8HOURS', 'NOW'), producttype='SLC')
OrderedDict([('04548172-c64a-418f-8e83-7a4d148adf1e',
              {'acquisitiontype': 'NOMINAL',
               'beginposition': datetime.datetime(2017, 4, 25, 15, 56, 12, 814000),
               'endposition': datetime.datetime(2017, 4, 25, 15, 56, 39, 758000),
               'filename': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF.SAFE',
               'footprint': 'POLYGON ((34.322010 0.401648,36.540989 0.876987,36.884121 -0.747357,34.664474 -1.227940,34.322010 0.401648))',
               'format': 'SAFE',
               'gmlfootprint': '<gml:Polygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" xmlns:gml="http://www.opengis.net/gml">\n   <gml:outerBoundaryIs>\n      <gml:LinearRing>\n         <gml:coordinates>0.401648,34.322010 0.876987,36.540989 -0.747357,36.884121 -1.227940,34.664474 0.401648,34.322010</gml:coordinates>\n      </gml:LinearRing>\n   </gml:outerBoundaryIs>\n</gml:Polygon>',
               'identifier': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF',
               'ingestiondate': datetime.datetime(2017, 4, 25, 19, 23, 45, 956000),
               'instrumentname': 'Synthetic Aperture Radar (C-band)',
               'instrumentshortname': 'SAR-C SAR',
               'lastorbitnumber': 16302,
               'lastrelativeorbitnumber': 130,
               'link': "https://scihub.copernicus.eu/apihub/odata/v1/Products('04548172-c64a-418f-8e83-7a4d148adf1e')/$value",
               'link_alternative': "https://scihub.copernicus.eu/apihub/odata/v1/Products('04548172-c64a-418f-8e83-7a4d148adf1e')/",
               'link_icon': "https://scihub.copernicus.eu/apihub/odata/v1/Products('04548172-c64a-418f-8e83-7a4d148adf1e')/Products('Quicklook')/$value",
               'missiondatatakeid': 110481,
               'orbitdirection': 'ASCENDING',
               'orbitnumber': 16302,
               'platformidentifier': '2014-016A',
               'platformname': 'Sentinel-1',
               'polarisationmode': 'VV VH',
               'productclass': 'S',
               'producttype': 'SLC',
               'relativeorbitnumber': 130,
               'sensoroperationalmode': 'IW',
               'size': '7.1 GB',
               'slicenumber': 8,
               'status': 'ARCHIVED',
               'summary': 'Date: 2017-04-25T15:56:12.814Z, Instrument: SAR-C SAR, Mode: VV VH, Satellite: Sentinel-1, Size: 7.1 GB',
               'swathidentifier': 'IW1 IW2 IW3',
               'title': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF',
               'uuid': '04548172-c64a-418f-8e83-7a4d148adf1e'}),
...

OData example

Only the most basic information available from the OData API is returned by default, if full=True is not set. The full metadata query response is quite large and not always nrequired, so it is not requested by default.

>>> api.get_product_odata('04548172-c64a-418f-8e83-7a4d148adf1e')
{'date': datetime.datetime(2017, 4, 25, 15, 56, 12, 814000),
 'footprint': 'POLYGON((34.322010 0.401648,36.540989 0.876987,36.884121 -0.747357,34.664474 -1.227940,34.322010 0.401648))',
 'id': '04548172-c64a-418f-8e83-7a4d148adf1e',
 'md5': 'E5855D1C974171D33EE4BC08B9D221AE',
 'size': 4633501134,
 'title': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF',
 'url': "https://scihub.copernicus.eu/apihub/odata/v1/Products('04548172-c64a-418f-8e83-7a4d148adf1e')/$value"}

With full=True we receive the full metadata available for the product.

>>> api.get_product_odata('04548172-c64a-418f-8e83-7a4d148adf1e', full=True)
{'Acquisition Type': 'NOMINAL',
 'Carrier rocket': 'Soyuz',
 'Cycle number': 107,
 'Date': datetime.datetime(2017, 4, 25, 15, 56, 12, 814000),
 'Filename': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF.SAFE',
 'Footprint': '<gml:Polygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" xmlns:gml="http://www.opengis.net/gml">\n   <gml:outerBoundaryIs>\n      <gml:LinearRing>\n         <gml:coordinates>0.401648,34.322010 0.876987,36.540989 -0.747357,36.884121 -1.227940,34.664474 0.401648,34.322010</gml:coordinates>\n      </gml:LinearRing>\n   </gml:outerBoundaryIs>\n</gml:Polygon>',
 'Format': 'SAFE',
 'Identifier': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF',
 'Ingestion Date': datetime.datetime(2017, 4, 25, 19, 23, 45, 956000),
 'Instrument': 'SAR-C',
 'Instrument abbreviation': 'SAR-C SAR',
 'Instrument description': '<a target="_blank" href="https://sentinel.esa.int/web/sentinel/missions/sentinel-1">https://sentinel.esa.int/web/sentinel/missions/sentinel-1</a>',
 'Instrument description text': 'The SAR Antenna Subsystem (SAS) is developed and build by AstriumGmbH. It is a large foldable planar phased array antenna, which isformed by a centre panel and two antenna side wings. In deployedconfiguration the antenna has an overall aperture of 12.3 x 0.84 m.The antenna provides a fast electronic scanning capability inazimuth and elevation and is based on low loss and highly stablewaveguide radiators build in carbon fibre technology, which arealready successfully used by the TerraSAR-X radar imaging mission.The SAR Electronic Subsystem (SES) is developed and build byAstrium Ltd. It provides all radar control, IF/ RF signalgeneration and receive data handling functions for the SARInstrument. The fully redundant SES is based on a channelisedarchitecture with one transmit and two receive chains, providing amodular approach to the generation and reception of wide-bandsignals and the handling of multi-polarisation modes. One keyfeature is the implementation of the Flexible Dynamic BlockAdaptive Quantisation (FD-BAQ) data compression concept, whichallows an efficient use of on-board storage resources and minimisesdownlink times.',
 'Instrument mode': 'IW',
 'Instrument name': 'Synthetic Aperture Radar (C-band)',
 'Instrument swath': 'IW1 IW2 IW3',
 'JTS footprint': 'POLYGON ((34.322010 0.401648,36.540989 0.876987,36.884121 -0.747357,34.664474 -1.227940,34.322010 0.401648))',
 'Launch date': 'April 3rd, 2014',
 'Mission datatake id': 110481,
 'Mission type': 'Earth observation',
 'Mode': 'IW',
 'NSSDC identifier': '2014-016A',
 'Operator': 'European Space Agency',
 'Orbit number (start)': 16302,
 'Orbit number (stop)': 16302,
 'Pass direction': 'ASCENDING',
 'Phase identifier': 1,
 'Polarisation': 'VV VH',
 'Product class': 'S',
 'Product class description': 'SAR Standard L1 Product',
 'Product composition': 'Slice',
 'Product level': 'L1',
 'Product type': 'SLC',
 'Relative orbit (start)': 130,
 'Relative orbit (stop)': 130,
 'Satellite': 'Sentinel-1',
 'Satellite description': '<a target="_blank" href="https://sentinel.esa.int/web/sentinel/missions/sentinel-1">https://sentinel.esa.int/web/sentinel/missions/sentinel-1</a>',
 'Satellite name': 'Sentinel-1',
 'Satellite number': 'A',
 'Sensing start': datetime.datetime(2017, 4, 25, 15, 56, 12, 814000),
 'Sensing stop': datetime.datetime(2017, 4, 25, 15, 56, 39, 758000),
 'Size': '7.1 GB',
 'Slice number': 8,
 'Start relative orbit number': 130,
 'Status': 'ARCHIVED',
 'Stop relative orbit number': 130,
 'Timeliness Category': 'Fast-24h',
 'date': datetime.datetime(2017, 4, 25, 15, 56, 12, 814000),
 'footprint': 'POLYGON((34.322010 0.401648,36.540989 0.876987,36.884121 -0.747357,34.664474 -1.227940,34.322010 0.401648))',
 'id': '04548172-c64a-418f-8e83-7a4d148adf1e',
 'md5': 'E5855D1C974171D33EE4BC08B9D221AE',
 'size': 4633501134,
 'title': 'S1A_IW_SLC__1SDV_20170425T155612_20170425T155639_016302_01AF91_46FF',
 'url': "https://scihub.copernicus.eu/apihub/odata/v1/Products('04548172-c64a-418f-8e83-7a4d148adf1e')/$value"}

Logging

Sentinelsat logs to sentinelsat and the API to sentinelsat.SentinelAPI.

There is no predefined logging handler, so in order to have your script print the log messages, either use logging.baseConfig

import logging

logging.basicConfig(format='%(message)s', level='INFO')

or add a custom handler for sentinelsat (as implemented in cli.py)

import logging

logger = logging.getLogger('sentinelsat')
logger.setLevel('INFO')

h = logging.StreamHandler()
h.setLevel('INFO')
fmt = logging.Formatter('%(message)s')
h.setFormatter(fmt)
logger.addHandler(h)

More Examples

Search Sentinel 2 by tile

To search for recent Sentinel 2 imagery by MGRS tile, use the tileid parameter:

from collections import OrderedDict
from sentinelsat import SentinelAPI

api = SentinelAPI('user', 'password')

tiles = ['33VUC', '33UUB']

query_kwargs = {
        'platformname': 'Sentinel-2',
        'producttype': 'S2MSI1C',
        'date': ('NOW-14DAYS', 'NOW')}

products = OrderedDict()
for tile in tiles:
    kw = query_kwargs.copy()
    kw['tileid'] = tile  # products after 2017-03-31
    pp = api.query(**kw)
    products.update(pp)

api.download_all(products)

NB: The tileid parameter only works for products from April 2017 onward due to missing metadata in SciHub’s DHuS catalogue. Before that, but only from December 2016 onward (i.e. for single-tile products), you can use a filename pattern instead:

kw['filename'] = '*_T{}_*'.format(tile)  # products after 2016-12-01

API

class sentinelsat.SentinelAPI(user, password, api_url='https://scihub.copernicus.eu/apihub/', show_progressbars=True)

Class to connect to Copernicus Open Access Hub, search and download imagery.

Parameters:
user : string

username for DataHub

password : string

password for DataHub

api_url : string, optional

URL of the DataHub defaults to ‘https://scihub.copernicus.eu/apihub

show_progressbars : bool

Whether progressbars should be shown or not, e.g. during download. Defaults to True.

Attributes:
session : requests.Session object

Session to connect to DataHub

api_url : str

URL to the DataHub

page_size : int

number of results per query page current value: 100 (maximum allowed on ApiHub)

Methods

check_files([paths, ids, directory, delete]) Verify the integrity of product files on disk.
check_query_length(query) Determine whether a query to the OpenSearch API is too long.
count([area, date, raw, area_relation]) Get the number of products matching a query.
download(id[, directory_path, checksum]) Download a product.
download_all(products[, directory_path, …]) Download a list of products.
format_query([area, date, raw, area_relation]) Create OpenSearch API query string
get_product_odata(id[, full]) Access OData API to get info about a product.
get_products_size(products) Return the total file size in GB of all products in the OpenSearch response
query([area, date, raw, area_relation, …]) Query the OpenSearch API with the coordinates of an area, a date interval and any other search keywords accepted by the API.
query_raw(query[, order_by, limit, offset]) Do a full-text query on the OpenSearch API using the format specified in https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch
to_dataframe(products) Return the products from a query response as a Pandas DataFrame with the values in their appropriate Python types.
to_geodataframe(products) Return the products from a query response as a GeoPandas GeoDataFrame with the values in their appropriate Python types.
to_geojson(products) Return the products from a query response as a GeoJSON with the values in their appropriate Python types.
check_files(paths=None, ids=None, directory=None, delete=False)

Verify the integrity of product files on disk.

Integrity is checked by comparing the size and checksum of the file with the respective values on the server.

The input can be a list of products to check or a list of IDs and a directory.

In cases where multiple products with different IDs exist on the server for given product name, the file is considered to be correct if any of them matches the file size and checksum. A warning is logged in such situations.

The corrupt products’ OData info is included in the return value to make it easier to re-download the products, if necessary.

Parameters:
paths : list[string]

List of product file paths.

ids : list[string]

List of product IDs.

directory : string

Directory where the files are located, if checking based on product IDs.

delete : bool

Whether to delete corrupt products. Defaults to False.

Returns:
dict[str, list[dict]]

A dictionary listing the invalid or missing files. The dictionary maps the corrupt file paths to a list of OData dictionaries of matching products on the server (as returned by SentinelAPI.get_product_odata()).

static check_query_length(query)

Determine whether a query to the OpenSearch API is too long.

The length of a query string is limited to approximately 3893 characters but any special characters (that is, not alphanumeric or -_.~) are counted twice towards that limit.

Parameters:
query : str

The query string

Returns:
float

Ratio of the query length to the maximum length

Notes

The query size limit arises from a limit on the length of the server’s internal query, which looks like

http://localhost:30333//solr/dhus/select?q=… &wt=xslt&tr=opensearch_atom.xsl&dhusLongName=Sentinels+Scientific+Data+Hub &dhusServer=https%3A%2F%2Fscihub.copernicus.eu%2Fapihub%2F&originalQuery=… &rows=100&start=0&sort=ingestiondate+desc

This function will estimate the length of the “q” and “originalQuery” parameters to determine whether the query will fail. Their combined length can be at most about 7786 bytes.

count(area=None, date=None, raw=None, area_relation='Intersects', **keywords)

Get the number of products matching a query.

This is a significantly more efficient alternative to doing len(api.query()), which can take minutes to run for queries matching thousands of products.

Parameters:
Identical to the parameters of api.query().
Returns:
int

The number of products matching a query.

download(id, directory_path='.', checksum=True)

Download a product.

Uses the filename on the server for the downloaded file, e.g. “S1A_EW_GRDH_1SDH_20141003T003840_20141003T003920_002658_002F54_4DD1.zip”.

Incomplete downloads are continued and complete files are skipped.

Parameters:
id : string

UUID of the product, e.g. ‘a8dd0cfd-613e-45ce-868c-d79177b916ed’

directory_path : string, optional

Where the file will be downloaded

checksum : bool, optional

If True, verify the downloaded file’s integrity by checking its MD5 checksum. Throws InvalidChecksumError if the checksum does not match. Defaults to True.

Returns:
product_info : dict

Dictionary containing the product’s info from get_product_info() as well as the path on disk.

Raises:
InvalidChecksumError

If the MD5 checksum does not match the checksum on the server.

download_all(products, directory_path='.', max_attempts=10, checksum=True)

Download a list of products.

Takes a list of product IDs as input. This means that the return value of query() can be passed directly to this method.

File names on the server are used for the downloaded files, e.g. “S1A_EW_GRDH_1SDH_20141003T003840_20141003T003920_002658_002F54_4DD1.zip”.

In case of interruptions or other exceptions, downloading will restart from where it left off. Downloading is attempted at most max_attempts times to avoid getting stuck with unrecoverable errors.

Parameters:
products : list

List of product IDs

directory_path : string

Directory where the downloaded files will be downloaded

max_attempts : int, optional

Number of allowed retries before giving up downloading a product. Defaults to 10.

Returns:
dict[string, dict]

A dictionary containing the return value from download() for each successfully downloaded product.

set[string]

The list of products that failed to download.

Other Parameters:
 
See download().
Raises:
Raises the most recent downloading exception if all downloads failed.
static format_query(area=None, date=None, raw=None, area_relation='Intersects', **keywords)

Create OpenSearch API query string

get_product_odata(id, full=False)

Access OData API to get info about a product.

Returns a dict containing the id, title, size, md5sum, date, footprint and download url of the product. The date field corresponds to the Start ContentDate value.

If full is set to True, then the full, detailed metadata of the product is returned in addition to the above. For a mapping between the OpenSearch (Solr) and OData attribute names see the following definition files: https://github.com/SentinelDataHub/DataHubSystem/blob/master/addon/sentinel-1/src/main/resources/META-INF/sentinel-1.owl https://github.com/SentinelDataHub/DataHubSystem/blob/master/addon/sentinel-2/src/main/resources/META-INF/sentinel-2.owl https://github.com/SentinelDataHub/DataHubSystem/blob/master/addon/sentinel-3/src/main/resources/META-INF/sentinel-3.owl

Parameters:
id : string

The ID of the product to query

full : bool

Whether to get the full metadata for the Product

Returns:
dict[str, Any]

A dictionary with an item for each metadata attribute

static get_products_size(products)

Return the total file size in GB of all products in the OpenSearch response

query(area=None, date=None, raw=None, area_relation='Intersects', order_by=None, limit=None, offset=0, **keywords)

Query the OpenSearch API with the coordinates of an area, a date interval and any other search keywords accepted by the API.

Parameters:
area : str, optional

The area of interest formatted as a Well-Known Text string.

date : tuple of (str or datetime) or str, optional

A time interval filter based on the Sensing Start Time of the products. Expects a tuple of (start, end), e.g. (“NOW-1DAY”, “NOW”). The timestamps can be either a Python datetime or a string in one of the following formats:

  • yyyyMMdd
  • yyyy-MM-ddThh:mm:ss.SSSZ (ISO-8601)
  • yyyy-MM-ddThh:mm:ssZ
  • NOW
  • NOW-<n>DAY(S) (or HOUR(S), MONTH(S), etc.)
  • NOW+<n>DAY(S)
  • yyyy-MM-ddThh:mm:ssZ-<n>DAY(S)
  • NOW/DAY (or HOUR, MONTH etc.) - rounds the value to the given unit

Alternatively, an already fully formatted string such as “[NOW-1DAY TO NOW]” can be used as well.

raw : str, optional

Additional query text that will be appended to the query.

area_relation : {‘Intersection’, ‘Contains’, ‘IsWithin’}, optional
What relation to use for testing the AOI. Case insensitive.
  • Intersects: true if the AOI and the footprint intersect (default)
  • Contains: true if the AOI is inside the footprint
  • IsWithin: true if the footprint is inside the AOI
order_by: str, optional

A comma-separated list of fields to order by (on server side). Prefix the field name by ‘+’ or ‘-‘ to sort in ascending or descending order, respectively. Ascending order is used, if prefix is omitted. Example: “cloudcoverpercentage, -beginposition”.

limit: int, optional

Maximum number of products returned. Defaults to no limit.

offset: int, optional

The number of results to skip. Defaults to 0.

Returns:
dict[string, dict]

Products returned by the query as a dictionary with the product ID as the key and the product’s attributes (a dictionary) as the value.

Other Parameters:
 
Additional keywords can be used to specify other query parameters,
e.g. relativeorbitnumber=70.
See https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch
for a full list.
Range values can be passed as two-element tuples, e.g. cloudcoverpercentage=(0, 30).
The time interval formats accepted by the ``date`` parameter can also be used with
any other parameters that expect time intervals (that is: ‘beginposition’, ‘endposition’,
‘date’, ‘creationdate’, and ‘ingestiondate’).
query_raw(query, order_by=None, limit=None, offset=0)
Do a full-text query on the OpenSearch API using the format specified in
https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch

DEPRECATED: use query(raw=…) instead. This method will be removed in the next major release.

Parameters:
query : str

The query string.

order_by: str, optional

A comma-separated list of fields to order by (on server side). Prefix the field name by ‘+’ or ‘-‘ to sort in ascending or descending order, respectively. Ascending order is used, if prefix is omitted. Example: “cloudcoverpercentage, -beginposition”.

limit: int, optional

Maximum number of products returned. Defaults to no limit.

offset: int, optional

The number of results to skip. Defaults to 0.

Returns:
dict[string, dict]

Products returned by the query as a dictionary with the product ID as the key and the product’s attributes (a dictionary) as the value.

static to_dataframe(products)

Return the products from a query response as a Pandas DataFrame with the values in their appropriate Python types.

static to_geodataframe(products)

Return the products from a query response as a GeoPandas GeoDataFrame with the values in their appropriate Python types.

static to_geojson(products)

Return the products from a query response as a GeoJSON with the values in their appropriate Python types.

sentinelsat.read_geojson(geojson_file)

Read a GeoJSON file into a GeoJSON object.

sentinelsat.geojson_to_wkt(geojson_obj, feature_number=0, decimals=4)

Convert a GeoJSON object to Well-Known Text. Intended for use with OpenSearch queries.

In case of FeatureCollection, only one of the features is used (the first by default). 3D points are converted to 2D.

Parameters:
geojson_obj : dict

a GeoJSON object

feature_number : int, optional

Feature to extract polygon from (in case of MultiPolygon FeatureCollection), defaults to first Feature

decimals : int, optional

Number of decimal figures after point to round coordinate to. Defaults to 4 (about 10 meters).

Returns:
polygon coordinates

string of comma separated coordinate tuples (lon, lat) to be used by SentinelAPI

Exceptions

exception sentinelsat.SentinelAPIError(msg=None, response=None)

Invalid responses from DataHub.

exception sentinelsat.InvalidChecksumError

MD5 checksum of a local file does not match the one from the server.