Queries ESA Sentinel APIs for products
- Free software: MIT license
import logging
from sentinelpy import (
query_sentinel_hub,
SentinelProductRequestBuilder,
RequestQueryBuilder,
PlatformName,
QuerySentinelProductsResponse
)
request = (
SentinelProductRequestBuilder()
.with_username("username")
.with_password("password")
.with_query(
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_1)
)
.build()
)
result = query_sentinel_hub(request, log_level=logging.DEBUG)
assert isinstance(result, QuerySentinelProductsResponse)
print(result.status_code)
print(result.body)
print(result.error)
Positional arguments:
-
sentinel_product_request
(SentinelProductRequest)Request object containing the details of the query. You should use the SentinelProductRequestBuilder to construct
Keyword arguments:
-
log_level
(int)Level for which to log at use
logging
to define correct level, defaults to 'INFO'. -
logger
(logging.Logger)Logger to use to log messages with, defaults to
logging.getLogger(__name__)
if no value supplied
Returns: QuerySentinelProductsResponse object
range_value
A helper function for defining range values for queries using the RequestQueryBuilder
Parameters:
-
start_val
(str)Start of the range
-
end_val
(str)End of the range
Returns: str range string in format of "[MIN TO MAX]" where MIN
is start_val
and MAX
is end_val
from sentinelpy import (
RequestQueryBuilder,
range_value
)
query = (
RequestQueryBuilder()
.orbit_number(range_value("1", "2"))
.build()
)
assert query == "orbitnumber:[1 TO 2]"
SentinelProductRequestBuilder
Builder resposible for creating SentinelProductRequest objects.
As a minimum, the username and password for the Sentinel Hub should be supplied.
Constructor details
default_query
(str): Default value for query, defaults to*
default_rows
(int): Default value for rows, defaults to30
default_order_by
(Optional[str]): Default value for order by, defaults toNone
default_start
(int): Default value for start, defaults to0
Method details
Method that constructs the SentinelProductRequest using the values supplied to the builder
Returns: SentinelProductRequest
- Built request from input data
Raises: ValueError
- if username or password missing
Sets the Sentinel Hub username
Parameter:
-
username
(str)The username for Sentinel Hub API
Returns: SentinelProductRequestBuilder Builder object with username
supplied
Sets the Sentinel Hub password
Parameter:
-
password
(str)The associated password for the user for the Sentinel Hub API
Returns: SentinelProductRequestBuilder Builder object with password
supplied
Sets the query (q) value
Parameter:
-
query
(str or RequestQueryBuilder)The query to use to filter results. If it is a RequestQueryBuilder, then
build
will callbuild
on the RequestQueryBuilder before constructing the SentinelProductRequest.
Returns: SentinelProductRequestBuilder Builder object with query
supplied
Sets the rows value
Parameter:
-
rows
(int)The value for rows to return in each request
Returns: SentinelProductRequestBuilder Builder object with rows
supplied
Sets the order_by value
Parameter:
-
order_by
(str)The value for order_by to return in each request
Returns: SentinelProductRequestBuilder Builder object with order_by
supplied
Sets the start value
Parameter:
-
start
(int)The value for start to return in each request
Returns: SentinelProductRequestBuilder Builder object with start
supplied
Example usage
from sentinelpy import (
SentinelProductRequestBuilder,
SentinelProductRequest,
RequestQueryBuilder,
PlatformName,
)
minimal = (
SentinelProductRequestBuilder()
.with_username("username")
.with_password("password")
.build()
)
assert minimal == SentinelProductRequest(
query="*",
rows=None,
order_by=None,
start=0,
username="username",
password="password"
)
full = (
SentinelProductRequestBuilder()
.with_username("username")
.with_password("password")
.with_query(
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_1)
)
.with_start(15)
.with_rows(15)
.with_order_by('ingestiondate desc')
.build()
)
assert full == SentinelProductRequest(
query="platformname:Sentinel-1",
rows=15,
order_by='ingestiondate desc',
start=15,
username="username",
password="password"
)
RequestQueryBuilder
A builder utility to build values for queries. Refer to the Sentinel Hub API documentation for more information about the values. The methods of this class map to search keywords/operators described in the former documentation. The keywords use snake case rather than all lowercase to adhere to Python conventions.
Method details
Creates the value for query/q
using the supplied values. If two non-operators supplied in order without an operator (i.e. and_
, or_
, or not_
)
defaults to and_
operator.
If the query has and_
or or_
operators at the start or an operator at the end then these are removed from the query.
Returns: str - the query constructed using the builder, if no methods called returns *
by default
Example
from sentinelpy import RequestQueryBuilder, PlatformName
default_build_behaviour = RequestQueryBuilder().build()
assert default_build_behaviour == "*"
hanging_operator_start = RequestQueryBuilder().and_().platform_name(PlatformName.SENTINEL_1).build()
assert hanging_operator_start == "platformname:Sentinel-1"
hanging_operator_end = RequestQueryBuilder().not_().platform_name(PlatformName.SENTINEL_1).and_().build()
assert hanging_operator_end == "NOT platformname:Sentinel-1"
Logical and
- combines the previous and next clauses i.e. platform_name(X).and_().platform_name(Y)
results in
the query being platformname:X AND platform_name:Y
Returns: RequestQueryBuilder self
Logical or
- either the previous or next clauses i.e. platform_name(X).or_().platform_name(Y)
results in
the query being platformname:X OR platform_name:Y
Returns: RequestQueryBuilder self
Negates the following clause.
Returns: RequestQueryBuilder self
Creates a grouped clause in the query. If the parameter is a RequestQueryBuilder then it calls the build
method
before.
Parameter:
-
inner_query
(str or RequestQueryBuilder)The query that is part of the group.
Returns: RequestQueryBuilder self
Example
from sentinelpy import (
RequestQueryBuilder,
PlatformName,
PolarisationMode
)
q = (
RequestQueryBuilder()
.group_(
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_1)
.and_()
.polarisation_mode(PolarisationMode.HH)
)
.or_()
.group_(
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_1)
.and_()
.not_()
.polarisation_mode(PolarisationMode.VH)
)
.build()
)
assert q == (
"(platformname:Sentinel-1 AND polarisationmode:HH) OR "
"(platformname:Sentinel-1 AND NOT polarisationmode:VH)"
)
Sets the beginposition filter between the parameters start/end
Parameters:
-
begin_position_start
(str)Start of the range that the query is interested in, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
-
begin_position_end
(str)End of the range that the query is interested in, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
Returns: RequestQueryBuilder self
Raises: ValueError - if begin_position_start
or begin_position_end
are not valid, i.e not ISO or relative
date
The range of acceptable values for cloud cover percentage as per Sentinel Dataset
Parameter:
-
percentage
(int or string)The percentage value or range (the format of
MIN TO MAX
where MIN is lowest acceptable and MAX is upper limit) of limit for Cloud Cover Percentage
Returns: RequestQueryBuilder self
Raises: ValueError if the value is not an integer or valid percentage or range
Set the value for collection. Used to specify the name of a predefined collection of products
Parameter:
-
collection
(str)Value for collection
Returns: RequestQueryBuilder self
Raises: ValueError if supplied string is empty i.e. '' or just whitespace
Set a filter on the range for endposition (that is Sensing Stop Time) that the query is interested in.
Parameter:
-
end_position_start
(str)Start of the period, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
-
end_position_end
(str)End of the period, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
Returns: RequestQueryBuilder self
Raises: ValueError - if end_position_start
or end_position_end
are not valid, i.e not ISO or relative
date
Sets a filter on product filename.
Parameter:
-
filename
(str)Name of the product file to filter results by
Returns: RequestQueryBuilder self
Raises: ValueError if supplied string is empty i.e. '' or just whitespace
Sets a filter on geographic area that the query is interested in. Can use either a simple bounding box described
as a WKT Polygon or a point described by a Latitude
Longitude
pair. Refer to the Sentinel Hub documentation for
in depth information about footprint.
Parameter:
-
geographic_type
(str)The Area of Interest for the query. Can either be a point (lat/lon pair e.g. "0.000, 1.000") or a Polygon (WKT polygon without cut outs, e.g. POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10)))
Can have the Intersects() or can be just the coordinate pair or Polygon
Returns: RequestQueryBuilder self
Raises: ValueError if not valid WKT Polygon or point
Sets a filter on the date the Sentinel product was ingested using the supplied range.
Parameter:
-
ingestion_date_start
(str)Start of the period, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
-
ingestion_date_end
(str)End of the period, in ISO date/time stamp with millis, or relative to NOW (e.g. NOW/NOW-1DAY etc.)
Returns: RequestQueryBuilder self
Raises: ValueError - if ingestion_date_start
or ingestion_date_end
are not valid, i.e not ISO or relative
Sets on a filter on the last orbit number or range range of last orbit numbers (i.e [MIN TO MAX]
whereby MIN
is the lowest last orbit number and MAX is highest).
Parameter:
-
orbit_number
(str or int)The orbit number or range that should be used. Can be a single value i.e. 1234 or a range such as [1234 TO 4321] must be between 0 and 999999
Returns: RequestQueryBuilder self
Raises: ValueError if value is not a valid number or range
Sets a filter on the last orbit number or range range of last orbit numbers (i.e [MIN TO MAX]
whereby MIN
is the lowest last orbit number and MAX is highest). Relative orbit number of the oldest line within the image
data (the start of the product) and relative orbit number of the most recent line within the image data
(the end of the product), respectively.
Parameter:
-
orbit_number
(str or int)The orbit number or range that should be used. Can be a single value i.e. 1234 or a range such as [1234 TO 4321] must be between 0 and 175
Returns: RequestQueryBuilder self
Raises: ValueError if value is not a valid number or range
Sets a filter on the orbit direction for the oldest data in the product
Parameter:
-
orbit_direction
(OrbitDirection)Direction that the query is interested in
Returns: RequestQueryBuilder self
Sets a filter on the orbit number or range range of orbit numbers (i.e [MIN TO MAX]
whereby MIN
is the lowest orbit number and MAX is highest).
Parameter:
-
orbit_number
(str or int)The orbit number or range that should be used. Can be a single value i.e. 1234 or a range such as [1234 TO 4321]. must be between 0 and 999999
Returns: RequestQueryBuilder self
Raises: ValueError if value is not a valid number or range
Sets a filter on the platform name
Parameter:
-
platform_name
(PlatformName)The platform name to filter the results by
Returns: RequestQueryBuilder self
Sets a filter on polarisation mode.
Parameter:
-
polarisation_mode
(PolarisationMode)Specified value for polarisation_mode
Returns: RequestQueryBuilder self
Sets a filter on product type. Note the valid combinations with platform_name
Parameter:
-
product_type
(Sentinel1ProductType
orSentinel2ProductType
orSentinel3ProductType
orSentinel5PProductType
)Specified value for product type to filter the results on
Returns: RequestQueryBuilder self
Set filter on relative orbit number of the oldest line within the image data (the start of the product).
Parameter:
-
orbit_number
(str or int)The orbit number or range that should be used. Can be a single value i.e. 123 or a range such as [123 TO 124]. must be between 0 and 175
Returns: RequestQueryBuilder self
Raises: ValueError if value is not a valid number or range
Set filter on sensor operational mode
Parameter:
-
sensor_operational_mode
(SensorOperationalMode)The value to filter products on
Returns: RequestQueryBuilder self
Search all valid swath identifiers for the Sentinel-1 SAR instrument. The S1-S6 swaths apply to SM products, the IW and IW1-3 swaths apply to IW products (IW is used for detected IW products where the 3 swaths are merged into one image), the EW and EW1-5 swaths apply to EW products (EW is used for detected EW products where the 5 swaths are merged into one image).
Parameter:
-
swath_identifier
(SwathIdentifier)Swath Identifier to filter products with
Returns: RequestQueryBuilder self
Filter sentinel products on timeliness
Parameter:
-
timeliness
(Timeliness)Value of timeliness that the query is interested in
Returns: RequestQueryBuilder self
Example
from sentinelpy import RequestQueryBuilder, PlatformName
simple_q = (
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_1)
.build()
)
assert simple_q == "platformname:Sentinel-1"
multiple_clauses_q = (
RequestQueryBuilder()
.platform_name(PlatformName.SENTINEL_3)
.and_()
.cloud_cover_percentage("[0 TO 5]")
.and_()
.footprint(
"POLYGON((-4.53 29.85, 26.75 29.85, 26.75 46.80,-4.53 46.80,-4.53 29.85))"
)
.build()
)
assert multiple_clauses_q == (
'platformname:Sentinel-3 AND cloudcoverpercentage:[0 TO 5] AND '
'footprint:"Intersects(POLYGON((-4.53 29.85, 26.75 29.85, 26.75 46.'
'80,-4.53 46.80,-4.53 29.85)))"'
)
SentinelProductRequest
Named Tuple representing a request. Best practice would be to use the builders (SentinelProductRequestBuilder and RequestQueryBuilder) to derive.
-
query
(str)Query string value for 'q' in the request. Sentinel hub documentation. This can be constructed using the RequestQueryBuilder.
-
rows
(int)Number of rows to return from the API Reference to documentation
-
order_by
(Optional[str])Field to order the results on Reference to documentation
-
start
(int)Start position of the records to return Reference to documentation
-
username
(str)Valid username to use to authenticate with the Sentinel Hub API
-
password
(str)Valid password to use to authenticate with the Sentinel Hub API
QuerySentinelProductsResponse
Represents the result from the Sentinel Hub API
Can be interacted with as an object or in a more functional style using
the 'on' methods (on_success
/on_failure
).
Property Details
-
status_code
(Optional[int])The HTTP Status code representing the outcome of the query
-
body
(Optional[Dict[str, Any]])The resulting data from the Sentinel Hub
-
error
(Optional[BaseException])An error object if there was an error or exception raised
-
success
(bool)Whether or not the query was successful
Method details
If encountered an error raise error encountered. Otherwise do nothing
Situations this would be useful:
- Prevent exceptions being swallowed
- You prefer to handle exception rather than checking if value is None
Returns: None
Raises: Error that was encountered when querying the API
A functional style method for handling successful results. When the action was successful, calls
the supplied function with data from Sentinel Hub API and returns the QuerySentinelProductsResponse
so that other methods can be chained
Parameters:
-
callback
: (Callable[[Dict[str, Any]], None]
)Function which defines the successful behaviour
Returns: QuerySentinelProductsResponse
self
A functional style method for handling cases where the API was not reachable or there was an error either in the response or parsing the response, i.e. the request was not successful.
Parameters:
-
callback
: (Callable[[QuerySentinelProductsResponse], None]
)Function which defines the failure behaviour, which will be called with named tuple representing the result
Returns: QuerySentinelProductsResponse
self
Example
from sentinelpy import QuerySentinelProductsResponse
# You can use the attributes of the response in a more object fashion
# Successful response:
successful_response = QuerySentinelProductsResponse(200, {})
assert successful_response.success
assert successful_response.status_code == 200
assert successful_response.body == {}
assert successful_response.error is None
# Failed response:
failed_response = QuerySentinelProductsResponse(400, {})
assert not failed_response.success
assert failed_response.status_code == 400
assert failed_response.body == {}
assert failed_response.error is None
# Erroneous response
erroneous_response = QuerySentinelProductsResponse(None, None, IOError())
assert not erroneous_response.success
assert erroneous_response.status_code is None
assert erroneous_response.body is None
assert isinstance(erroneous_response.error, IOError)
# Using the functional style methods
successful_response.on_success(
lambda data: print(f'success:{data}')
).on_failure(
lambda failure_response: print(f'failure:{failure_response.status_code}')
) # success:{}
failed_response.on_success(
lambda data: print(f'success:{data}')
).on_failure(
lambda failure_response: print(f'failure:{failure_response.status_code}')
) # failure:400
Enumerations
In order to simplify validation there are some Enumerations representing some of the types in the RequestQueryBuilder
, each
valid option maps to a value defined by the API. Refer to the Sentinel Hub API documentation for more information about the values
The enumerations are as follows:
OrbitDirection
PlatformName
PolarisationMode
ProductType
SensorOperationalMode
Sentinel1ProductType
Sentinel2ProductType
Sentinel3ProductType
Sentinel5PProductType
SwathIdentifier
Timeliness
- Queries the Sentinel Hub for products
- Define your requests using the
RequestQueryBuilder
andSentinelProductRequestBuilder
objects
Built using Poetry.
poetry install
To install the library locally from source
This package was created with Cookiecutter and the UKHO/cookiecutter-pypackage
project template.
- Cookiecutter: https://github.com/cookiecutter/cookiecutter
- UKHO/cookiecutter-pypackage: https://github.com/UKHO/cookiecutter-pypackage