Skip to content

Python Library for querying Sentinel Hub API for products

License

Notifications You must be signed in to change notification settings

UKHO/sentinelpy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sentinelpy

Python Package Dependabot Status PyPI - Downloads

Queries ESA Sentinel APIs for products

  • Free software: MIT license

Usage

query_sentinel_hub

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:

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

API Documentation

range_value

range_value (function)

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

Example

from sentinelpy import (
    RequestQueryBuilder,
    range_value
)

query = (
    RequestQueryBuilder()
    .orbit_number(range_value("1", "2"))
    .build()
)

assert query == "orbitnumber:[1 TO 2]"


SentinelProductRequestBuilder

SentinelProductRequestBuilder (class)

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 to 30
  • default_order_by (Optional[str]): Default value for order by, defaults to None
  • default_start (int): Default value for start, defaults to 0

Method details

build

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


with_username

Sets the Sentinel Hub username

Parameter:

  • username (str)

    The username for Sentinel Hub API

Returns: SentinelProductRequestBuilder Builder object with username supplied


with_password

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


with_query

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 call build on the RequestQueryBuilder before constructing the SentinelProductRequest.

Returns: SentinelProductRequestBuilder Builder object with query supplied


with_rows

Sets the rows value

Parameter:

  • rows (int)

    The value for rows to return in each request

Returns: SentinelProductRequestBuilder Builder object with rows supplied


with_order_by

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


with_start

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

RequestQueryBuilder (class)

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

build

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"

and_

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


or_

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


not_

Negates the following clause.

Returns: RequestQueryBuilder self


group_

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)"
)

begin_position

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


cloud_cover_percentage

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


collection

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


end_position

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


file_name

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


footprint

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


ingestion_date

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


last_orbit_number

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


last_relative_orbit_number

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


orbit_direction

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


orbit_number

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


platform_name

Sets a filter on the platform name

Parameter:

  • platform_name (PlatformName)

    The platform name to filter the results by

Returns: RequestQueryBuilder self


polarisation_mode

Sets a filter on polarisation mode.

Parameter:

Returns: RequestQueryBuilder self


product_type

Sets a filter on product type. Note the valid combinations with platform_name

Parameter:

Returns: RequestQueryBuilder self


relative_orbit_number

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


sensor_operational_mode

Set filter on sensor operational mode

Parameter:

Returns: RequestQueryBuilder self


swath_identifier

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


timeliness

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

SentinelProductRequest (NamedTuple/class)

Named Tuple representing a request. Best practice would be to use the builders (SentinelProductRequestBuilder and RequestQueryBuilder) to derive.

Properties:


QuerySentinelProductsResponse

QuerySentinelProductsResponse (NamedTuple/class)

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

raise_error

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


on_success

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


on_failure

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

Features

  • Queries the Sentinel Hub for products
  • Define your requests using the RequestQueryBuilder and SentinelProductRequestBuilder objects

Development Documentation

Built using Poetry.

poetry install

To install the library locally from source

Credits

This package was created with Cookiecutter and the UKHO/cookiecutter-pypackage project template.