BYOC API Examples
The following API requests are written in Python.
To execute them, create an OAuth client. Refer to the authentication process for guidance.
The client is named oauth in these examples.
The examples are structured to be as separable as possible; however, in many cases it is advisable to follow all the steps in each chapter.
In the following examples, AWS EU (eu-central-1) URL end-point https://services.sentinel-hub.com/api/v1/byoc is used; however if your data is stored in a different location, you need to replace the URL. Refer to BYOC deployment to find the respective URL end-point.
Creating a Collection
To create a collection with the name <MyCollection> and S3 bucket <MyBucket>:
- Python SDK
collection = {
'name': '<MyCollection>',
's3Bucket': '<MyBucket>'
}
response = oauth.post('https://services.sentinel-hub.com/api/v1/byoc/collections', json=collection)
response.raise_for_status()
Extracting the collection 'id' from the response:
- Python SDK
import json
collection = json.loads(response.text)['data']
collection_id = collection['id']
Creating a Tile
To create a tile with the path <MyTile>:
- Python SDK
tile = {
'path': '<MyTile>',
}
response = oauth.post(f'https://services.sentinel-hub.com/api/v1/byoc/collections/{collection_id}/tiles', json=tile)
response.raise_for_status()
If your tile has a known sensing time, for example, October 21, 2019 at 14:51 UTC time, add this information by using the following payload:
- Python SDK
tile = {
'path': '<MyTile>',
'sensingTime': '2019-10-21T14:51:00Z'
}
If you want to provide a cover geometry, set it as the value of the coverGeometry field:
- Python SDK
tile = {
'path': '<MyTile>',
'coverGeometry': <MyCoverGeometry>
}
For information on how to prepare a cover geometry, see Preparing a cover geometry.
To extract the tile 'id' from the response:
- Python SDK
import json
tile = json.loads(response.text)['data']
tile_id = tile['id']
Preparing a Cover Geometry
To obtain a cover geometry automatically, you can use the gdal_trace_outline script which gives you a cover geometry in the WKT format:
- Python SDK
import subprocess
command = f'gdal_trace_outline <MyCOG> -out-cs en -wkt-out wkt.txt'
subprocess.run(command, shell=True, check=True)
Once complete, transform the geometry into the following GeoJSON format:
- Python SDK
from osgeo import ogr
import json
f = open('wkt.txt')
geom = ogr.CreateGeometryFromWkt(f.read())
cover_geometry = json.loads(geom.ExportToJson())
If the CRS is something other than WGS84, make sure to set its URN <CrsUrn> under crs.properties.name. For example, urn:ogc:def:crs:EPSG::32633 for EPSG:32633.
- Python SDK
cover_geometry['crs'] = {
'properties': {
'name': '<CrsUrn>'
}
}
To obtain the URN automatically from a raster file you can use the following Python scriptget_crn_urn.py.
Checking the Tile Ingestion Status
To check the ingestion status of the tile, first get the tile:
- Python SDK
response = oauth.get(f'https://services.sentinel-hub.com/api/v1/byoc/collections/{collection_id}/tiles/{tile_id}')
response.raise_for_status()
Then extract the status from the response:
- Python SDK
import json
tile = json.loads(response.text)['data']
status = tile['status']
if status == 'INGESTED':
print('Tile ingested')
elif status == 'FAILED':
print('Tile failed to ingest')
else:
print(status)
To check why a tile failed to ingest:
- Python SDK
print(tile['additionalData']['failedIngestionCause'])
Listing Tiles
Tiles are paginated and to traverse all pages use the link from the response that points to the next page, which is located at links.next.
By default, you receive 100 tiles per page, but you can change this using the query parameter count; however, it cannot be more than 100.
- Python SDK
import time
url = f'https://services.sentinel-hub.com/api/v1/byoc/collections/{collection_id}/tiles'
while url is not None:
response = oauth.get(url)
response.raise_for_status()
output = response.json()
tiles = output['data']
links = output['links']
for tile in tiles:
print(tile['path'])
# sets url to None if there is no link to the next set of tiles
url = links.get('next', None)
# waits before fetching the next set
time.sleep(0.1)