import requests
from owslib.ogcapi.records import Records
from owslib.util import Authentication
import json
Ingesting STAC metadata in APEx Product Catalogue
This notebook demonstrates how to add STAC metadata to an APEx Product Catalogue. Since STAC is a widely adopted specification, existing STAC documentation may also be useful for understanding its broader applications.
Creating STAC metadata from scratch
In this first part, we provide a basic example of how to manually create STAC metadata from scratch. However, in most real-world cases, this approach is not needed nor recommended. Instead, various tools and platforms will generate STAC metadata for you.
The STAC metadata in this example is entirely fictional and not intended for practical use. It does not demonstrate how to create high-quality, FAIR-compliant metadata but serves purely as a demonstration of the STAC API and its ease of use. Most of the more complex examples and tools will avoid this type of direct interaction.
For ease of use, we define the URL of the APEx catalogue here. This allows us to reuse it as a reference throughout the notebook.
= "https://catalogue.demo.apex.esa.int" CATALOGUE
Authentication for APEx Product Catalogue
To interact with an APEx Product Catalogue, you need a valid authentication token. This token ensures that you can write metadata to an APEx-initialized STAC catalogue, provided you have been granted sufficient access rights.
To obtain an authentication token, follow the dedicated guide on generating your OIDC token. This step is essential for securely accessing and modifying catalogue records.
# Helper class to support the authentication with owslib and requests libraries
class BearerAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token
def __call__(self, r):
"authorization"] = "Bearer " + self.token
r.headers[return r
= input("Please provide your OIDC token here")
token = BearerAuth(token) auth
= Records(CATALOGUE,auth=Authentication(auth_delegate=auth))
r print(json.dumps(r.collections(), indent=2))
{
"collections": [],
"links": [
{
"rel": "root",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
},
{
"rel": "parent",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
},
{
"rel": "self",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/collections"
}
]
}
Exploring the dataset
Before creating the STAC metadata, it’s useful to explore the dataset. This helps in understanding key properties such as spatial extent, resolution, and format.
A quick way to retrieve metadata from a representative asset is by using the gdalinfo
command. Running this command provides useful details, including:
- Projection and coordinate system
- Bounding box and spatial resolution
- Number of bands and data type
- …
This information will guide the creation of accurate STAC metadata for the dataset.
!GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR gdalinfo -json "/vsicurl/https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif"
{
"description":"/vsicurl/https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif",
"driverShortName":"GTiff",
"driverLongName":"GeoTIFF",
"files":[
"/vsicurl/https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif"
],
"size":[
40888,
41712
],
"coordinateSystem":{
"wkt":"PROJCRS[\"ETRS89-extended / LAEA Europe\",\n BASEGEOGCRS[\"ETRS89\",\n ENSEMBLE[\"European Terrestrial Reference System 1989 ensemble\",\n MEMBER[\"European Terrestrial Reference Frame 1989\"],\n MEMBER[\"European Terrestrial Reference Frame 1990\"],\n MEMBER[\"European Terrestrial Reference Frame 1991\"],\n MEMBER[\"European Terrestrial Reference Frame 1992\"],\n MEMBER[\"European Terrestrial Reference Frame 1993\"],\n MEMBER[\"European Terrestrial Reference Frame 1994\"],\n MEMBER[\"European Terrestrial Reference Frame 1996\"],\n MEMBER[\"European Terrestrial Reference Frame 1997\"],\n MEMBER[\"European Terrestrial Reference Frame 2000\"],\n MEMBER[\"European Terrestrial Reference Frame 2005\"],\n MEMBER[\"European Terrestrial Reference Frame 2014\"],\n MEMBER[\"European Terrestrial Reference Frame 2020\"],\n ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[0.1]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4258]],\n CONVERSION[\"Europe Equal Area 2001\",\n METHOD[\"Lambert Azimuthal Equal Area\",\n ID[\"EPSG\",9820]],\n PARAMETER[\"Latitude of natural origin\",52,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8801]],\n PARAMETER[\"Longitude of natural origin\",10,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"False easting\",4321000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",3210000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"northing (Y)\",north,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"easting (X)\",east,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Statistical analysis.\"],\n AREA[\"Europe - European Union (EU) countries and candidates. Europe - onshore and offshore: Albania; Andorra; Austria; Belgium; Bosnia and Herzegovina; Bulgaria; Croatia; Cyprus; Czechia; Denmark; Estonia; Faroe Islands; Finland; France; Germany; Gibraltar; Greece; Hungary; Iceland; Ireland; Italy; Kosovo; Latvia; Liechtenstein; Lithuania; Luxembourg; Malta; Monaco; Montenegro; Netherlands; North Macedonia; Norway including Svalbard and Jan Mayen; Poland; Portugal including Madeira and Azores; Romania; San Marino; Serbia; Slovakia; Slovenia; Spain including Canary Islands; Sweden; Switzerland; Türkiye (Turkey); United Kingdom (UK) including Channel Islands and Isle of Man; Vatican City State.\"],\n BBOX[24.6,-35.58,84.73,44.83]],\n ID[\"EPSG\",3035]]",
"dataAxisToSRSAxisMapping":[
2,
1
]
},
"geoTransform":[
2515000.0,
100.0,
0.0,
5512800.0,
0.0,
-100.0
],
"metadata":{
"":{
"AREA_OR_POINT":"Area"
},
"IMAGE_STRUCTURE":{
"LAYOUT":"COG",
"COMPRESSION":"DEFLATE",
"INTERLEAVE":"BAND",
"PREDICTOR":"2"
}
},
"cornerCoordinates":{
"upperLeft":[
2515000.0,
5512800.0
],
"lowerLeft":[
2515000.0,
1341600.0
],
"lowerRight":[
6603800.0,
1341600.0
],
"upperRight":[
6603800.0,
5512800.0
],
"center":[
4559400.0,
3427200.0
]
},
"wgs84Extent":{
"type":"Polygon",
"coordinates":[
[
[
-35.0421748,
67.1549879
],
[
-9.3033749,
33.067326
],
[
34.1876844,
31.8603398
],
[
62.8622654,
64.3475852
],
[
-35.0421748,
67.1549879
]
]
]
},
"bands":[
{
"band":1,
"block":[
512,
512
],
"type":"UInt16",
"colorInterpretation":"Gray",
"noDataValue":65535.0,
"overviews":[
{
"size":[
20444,
20856
]
},
{
"size":[
10222,
10428
]
},
{
"size":[
5111,
5214
]
},
{
"size":[
2555,
2607
]
},
{
"size":[
1277,
1303
]
},
{
"size":[
638,
651
]
},
{
"size":[
319,
325
]
}
],
"metadata":{}
}
],
"stac":{
"proj:shape":[
41712,
40888
],
"proj:wkt2":"PROJCRS[\"ETRS89-extended / LAEA Europe\",\n BASEGEOGCRS[\"ETRS89\",\n ENSEMBLE[\"European Terrestrial Reference System 1989 ensemble\",\n MEMBER[\"European Terrestrial Reference Frame 1989\"],\n MEMBER[\"European Terrestrial Reference Frame 1990\"],\n MEMBER[\"European Terrestrial Reference Frame 1991\"],\n MEMBER[\"European Terrestrial Reference Frame 1992\"],\n MEMBER[\"European Terrestrial Reference Frame 1993\"],\n MEMBER[\"European Terrestrial Reference Frame 1994\"],\n MEMBER[\"European Terrestrial Reference Frame 1996\"],\n MEMBER[\"European Terrestrial Reference Frame 1997\"],\n MEMBER[\"European Terrestrial Reference Frame 2000\"],\n MEMBER[\"European Terrestrial Reference Frame 2005\"],\n MEMBER[\"European Terrestrial Reference Frame 2014\"],\n MEMBER[\"European Terrestrial Reference Frame 2020\"],\n ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[0.1]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4258]],\n CONVERSION[\"Europe Equal Area 2001\",\n METHOD[\"Lambert Azimuthal Equal Area\",\n ID[\"EPSG\",9820]],\n PARAMETER[\"Latitude of natural origin\",52,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8801]],\n PARAMETER[\"Longitude of natural origin\",10,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"False easting\",4321000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",3210000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"northing (Y)\",north,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"easting (X)\",east,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Statistical analysis.\"],\n AREA[\"Europe - European Union (EU) countries and candidates. Europe - onshore and offshore: Albania; Andorra; Austria; Belgium; Bosnia and Herzegovina; Bulgaria; Croatia; Cyprus; Czechia; Denmark; Estonia; Faroe Islands; Finland; France; Germany; Gibraltar; Greece; Hungary; Iceland; Ireland; Italy; Kosovo; Latvia; Liechtenstein; Lithuania; Luxembourg; Malta; Monaco; Montenegro; Netherlands; North Macedonia; Norway including Svalbard and Jan Mayen; Poland; Portugal including Madeira and Azores; Romania; San Marino; Serbia; Slovakia; Slovenia; Spain including Canary Islands; Sweden; Switzerland; Türkiye (Turkey); United Kingdom (UK) including Channel Islands and Isle of Man; Vatican City State.\"],\n BBOX[24.6,-35.58,84.73,44.83]],\n ID[\"EPSG\",3035]]",
"proj:epsg":3035,
"proj:projjson":{
"$schema":"https://proj.org/schemas/v0.7/projjson.schema.json",
"type":"ProjectedCRS",
"name":"ETRS89-extended / LAEA Europe",
"base_crs":{
"name":"ETRS89",
"datum_ensemble":{
"name":"European Terrestrial Reference System 1989 ensemble",
"members":[
{
"name":"European Terrestrial Reference Frame 1989",
"id":{
"authority":"EPSG",
"code":1178
}
},
{
"name":"European Terrestrial Reference Frame 1990",
"id":{
"authority":"EPSG",
"code":1179
}
},
{
"name":"European Terrestrial Reference Frame 1991",
"id":{
"authority":"EPSG",
"code":1180
}
},
{
"name":"European Terrestrial Reference Frame 1992",
"id":{
"authority":"EPSG",
"code":1181
}
},
{
"name":"European Terrestrial Reference Frame 1993",
"id":{
"authority":"EPSG",
"code":1182
}
},
{
"name":"European Terrestrial Reference Frame 1994",
"id":{
"authority":"EPSG",
"code":1183
}
},
{
"name":"European Terrestrial Reference Frame 1996",
"id":{
"authority":"EPSG",
"code":1184
}
},
{
"name":"European Terrestrial Reference Frame 1997",
"id":{
"authority":"EPSG",
"code":1185
}
},
{
"name":"European Terrestrial Reference Frame 2000",
"id":{
"authority":"EPSG",
"code":1186
}
},
{
"name":"European Terrestrial Reference Frame 2005",
"id":{
"authority":"EPSG",
"code":1204
}
},
{
"name":"European Terrestrial Reference Frame 2014",
"id":{
"authority":"EPSG",
"code":1206
}
},
{
"name":"European Terrestrial Reference Frame 2020",
"id":{
"authority":"EPSG",
"code":1382
}
}
],
"ellipsoid":{
"name":"GRS 1980",
"semi_major_axis":6378137,
"inverse_flattening":298.257222101
},
"accuracy":"0.1",
"id":{
"authority":"EPSG",
"code":6258
}
},
"coordinate_system":{
"subtype":"ellipsoidal",
"axis":[
{
"name":"Geodetic latitude",
"abbreviation":"Lat",
"direction":"north",
"unit":"degree"
},
{
"name":"Geodetic longitude",
"abbreviation":"Lon",
"direction":"east",
"unit":"degree"
}
]
},
"id":{
"authority":"EPSG",
"code":4258
}
},
"conversion":{
"name":"Europe Equal Area 2001",
"method":{
"name":"Lambert Azimuthal Equal Area",
"id":{
"authority":"EPSG",
"code":9820
}
},
"parameters":[
{
"name":"Latitude of natural origin",
"value":52,
"unit":"degree",
"id":{
"authority":"EPSG",
"code":8801
}
},
{
"name":"Longitude of natural origin",
"value":10,
"unit":"degree",
"id":{
"authority":"EPSG",
"code":8802
}
},
{
"name":"False easting",
"value":4321000,
"unit":"metre",
"id":{
"authority":"EPSG",
"code":8806
}
},
{
"name":"False northing",
"value":3210000,
"unit":"metre",
"id":{
"authority":"EPSG",
"code":8807
}
}
]
},
"coordinate_system":{
"subtype":"Cartesian",
"axis":[
{
"name":"Northing",
"abbreviation":"Y",
"direction":"north",
"unit":"metre"
},
{
"name":"Easting",
"abbreviation":"X",
"direction":"east",
"unit":"metre"
}
]
},
"scope":"Statistical analysis.",
"area":"Europe - European Union (EU) countries and candidates. Europe - onshore and offshore: Albania; Andorra; Austria; Belgium; Bosnia and Herzegovina; Bulgaria; Croatia; Cyprus; Czechia; Denmark; Estonia; Faroe Islands; Finland; France; Germany; Gibraltar; Greece; Hungary; Iceland; Ireland; Italy; Kosovo; Latvia; Liechtenstein; Lithuania; Luxembourg; Malta; Monaco; Montenegro; Netherlands; North Macedonia; Norway including Svalbard and Jan Mayen; Poland; Portugal including Madeira and Azores; Romania; San Marino; Serbia; Slovakia; Slovenia; Spain including Canary Islands; Sweden; Switzerland; Türkiye (Turkey); United Kingdom (UK) including Channel Islands and Isle of Man; Vatican City State.",
"bbox":{
"south_latitude":24.6,
"west_longitude":-35.58,
"north_latitude":84.73,
"east_longitude":44.83
},
"id":{
"authority":"EPSG",
"code":3035
}
},
"proj:transform":[
2515000.0,
100.0,
0.0,
5512800.0,
0.0,
-100.0
],
"raster:bands":[
{
"data_type":"uint16",
"nodata":null
}
],
"eo:bands":[
{
"name":"b1",
"description":"Gray"
}
]
}
}
Creating a STAC collection
Now, we will construct and register the STAC collection from scratch using the pystac
library. The STAC collection is used to store all of the assets of our dataset.
from datetime import datetime
import pystac
= pystac.SpatialExtent(bboxes=[[4,51,5,52]])
spatial_extent = sorted([datetime(2020,1,1), datetime(2022,1,1)])
collection_interval = pystac.TemporalExtent(intervals=[collection_interval])
temporal_extent
= """
description_markdown SOC content in the 0-20 cm top soil expressed in g kg-1 for 100 m resolution pixels
Applications:
- First globally consistent and contiguous complete gridded soil property map of Europe
- Indicator of soil health, as per Mission Area Soil Health and Food
- By 2030, at least 75% of soils in each EU Member State should be in healthy condition or show a
significant improvement towards meeting accepted thresholds of indicators, to support ecosystem
services
*Reliability*: More than 83 % of the cross-validation points fall within the 70% prediction interval for the bare soil model.
For the vegetated area model 94 % of the points fall within the 90 % prediction interval.
"""
= {
item_assets "SOC": {
"type": "image/tiff; application=geotiff; profile=cloud-optimized",
"title": "SOC",
"description": "SOC content in the 0-20 cm top soil expressed in g kg-1",
"data_type": "uint16",
"nodata": 65535,
"unit": "g kg-1",
"roles": [
"data"
]
}
}
= pystac.Extent(spatial=spatial_extent, temporal=temporal_extent)
collection_extent = pystac.Collection(id='esa-worldsoils',
collection =description_markdown,
description=collection_extent,
extent=dict(item_assets=item_assets),
extra_fields='CC-BY-SA-4.0')
license
"proj:code",["EPSG:3035"])
collection.summaries.add("gsd",[100])
collection.summaries.add("bands",[{
collection.summaries.add("title": "SOC",
"gsd": 100
}])
print(json.dumps(collection.to_dict(), indent=2))
{
"type": "Collection",
"id": "esa-worldsoils",
"stac_version": "1.1.0",
"description": "\nSOC content in the 0-20 cm top soil expressed in g kg-1 for 100 m resolution pixels\n\nApplications:\n\n- First globally consistent and contiguous complete gridded soil property map of Europe\n- Indicator of soil health, as per Mission Area Soil Health and Food\n- By 2030, at least 75% of soils in each EU Member State should be in healthy condition or show a\nsignificant improvement towards meeting accepted thresholds of indicators, to support ecosystem\nservices\n\n*Reliability*: More than 83 % of the cross-validation points fall within the 70% prediction interval for the bare soil model.\nFor the vegetated area model 94 % of the points fall within the 90 % prediction interval.\n",
"links": [],
"item_assets": {
"SOC": {
"type": "image/tiff; application=geotiff; profile=cloud-optimized",
"title": "SOC",
"description": "SOC content in the 0-20 cm top soil expressed in g kg-1",
"data_type": "uint16",
"nodata": 65535,
"unit": "g kg-1",
"roles": [
"data"
]
}
},
"extent": {
"spatial": {
"bbox": [
[
4,
51,
5,
52
]
]
},
"temporal": {
"interval": [
[
"2020-01-01T00:00:00Z",
"2022-01-01T00:00:00Z"
]
]
}
},
"license": "CC-BY-SA-4.0",
"summaries": {
"proj:code": [
"EPSG:3035"
],
"gsd": [
100
],
"bands": [
{
"title": "SOC",
"gsd": 100
}
]
}
}
To ensure the proper permissions are applied to our collection, we restrict write access to only the STAC administrators defined within our project. These administrators are assigned the stac-admin-<environment>
role, granting them exclusive rights to add content to the collection.
Read permissions are set to public, allowing unrestricted access for viewing the collection.
= collection.to_dict()
coll_dict
= {
default_auth "_auth": {
"read": ["anonymous"],
"write": ["stac-admin-prod"]
}
}
coll_dict.update(default_auth)
Finally, we send a request to the /collections
endpoint to create the new collection
= requests.post(f"{CATALOGUE}/collections", auth=auth,json=coll_dict)
response response
<Response [201]>
We can verify the creation of the collection by querying the collections from the catalogue.
print(json.dumps(r.collections()['collections'][0], indent=2))
{
"id": "esa-worldsoils",
"description": "\nSOC content in the 0-20 cm top soil expressed in g kg-1 for 100 m resolution pixels\n\nApplications:\n\n- First globally consistent and contiguous complete gridded soil property map of Europe\n- Indicator of soil health, as per Mission Area Soil Health and Food\n- By 2030, at least 75% of soils in each EU Member State should be in healthy condition or show a\nsignificant improvement towards meeting accepted thresholds of indicators, to support ecosystem\nservices\n\n*Reliability*: More than 83 % of the cross-validation points fall within the 70% prediction interval for the bare soil model.\nFor the vegetated area model 94 % of the points fall within the 90 % prediction interval.\n",
"stac_version": "1.1.0",
"links": [
{
"rel": "items",
"type": "application/geo+json",
"href": "https://catalogue.demo.apex.esa.int/collections/esa-worldsoils/items"
},
{
"rel": "parent",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
},
{
"rel": "root",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
},
{
"rel": "self",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/collections"
}
],
"type": "Collection",
"license": "CC-BY-SA-4.0",
"extent": {
"spatial": {
"bbox": [
[
4.0,
51.0,
5.0,
52.0
]
]
},
"temporal": {
"interval": [
[
"2020-01-01T00:00:00Z",
"2022-01-01T00:00:00Z"
]
]
}
},
"summaries": {
"proj:code": [
"EPSG:3035"
],
"gsd": [
100
],
"bands": [
{
"title": "SOC",
"gsd": 100
}
]
},
"item_assets": {
"SOC": {
"type": "image/tiff; application=geotiff; profile=cloud-optimized",
"title": "SOC",
"description": "SOC content in the 0-20 cm top soil expressed in g kg-1",
"data_type": "uint16",
"nodata": 65535,
"unit": "g kg-1",
"roles": [
"data"
]
}
},
"stac_extensions": [],
"title": "",
"keywords": [],
"providers": [],
"assets": {}
}
Creating the STAC item
In this step, we will create and register a dedicated STAC item to represent an element from our dataset. As mentioned earlier, this approach is generally not recommended, as most tools automatically generate STAC metadata for you.
import shapely
= {
geometry "type":"Polygon",
"coordinates":[
[
[-35.0421748,
67.1549879
],
[-9.3033749,
33.067326
],
[34.1876844,
31.8603398
],
[62.8622654,
64.3475852
],
[-35.0421748,
67.1549879
]
]
]
}
= shapely.geometry.shape(geometry).bounds
item_bbox = pystac.Item(id='europe_aggr-orgc_00-020_mean_100_202003-202210',
collection_item =geometry,
geometry= item_bbox,
bbox =datetime(2022,3,1),
datetime=collection.id,
collection={})
properties
= 100
collection_item.common_metadata.gsd
= pystac.Asset(href="https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif",
asset =pystac.MediaType.GEOTIFF, roles=["data"])
media_type"SOC", asset)
collection_item.add_asset(
print(json.dumps(collection_item.to_dict(), indent=2))
{
"type": "Feature",
"stac_version": "1.1.0",
"stac_extensions": [],
"id": "europe_aggr-orgc_00-020_mean_100_202003-202210",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-35.0421748,
67.1549879
],
[
-9.3033749,
33.067326
],
[
34.1876844,
31.8603398
],
[
62.8622654,
64.3475852
],
[
-35.0421748,
67.1549879
]
]
]
},
"bbox": [
-35.0421748,
31.8603398,
62.8622654,
67.1549879
],
"properties": {
"gsd": 100,
"datetime": "2022-03-01T00:00:00Z"
},
"links": [],
"assets": {
"SOC": {
"href": "https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif",
"type": "image/tiff; application=geotiff",
"roles": [
"data"
]
}
},
"collection": "esa-worldsoils"
}
After creating the STAC metadata, we can now add it to our collection.
id, collection_item.to_dict()) r.collection_item_create(collection.
True
We can verify the existing if the item was created by retrieving all of the collection items.
print(json.dumps(r.collection_items(collection.id), indent=2))
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"stac_version": "1.1.0",
"stac_extensions": [],
"id": "europe_aggr-orgc_00-020_mean_100_202003-202210",
"collection": "esa-worldsoils",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-35.0421748,
67.1549879
],
[
-9.3033749,
33.067326
],
[
34.1876844,
31.8603398
],
[
62.8622654,
64.3475852
],
[
-35.0421748,
67.1549879
]
]
]
},
"bbox": [
-35.0421748,
31.8603398,
62.8622654,
67.1549879
],
"properties": {
"datetime": "2022-03-01T00:00:00Z",
"gsd": 100.0,
"created": "2025-03-07T10:14:49.124241Z",
"updated": "2025-03-07T10:14:49.124241Z"
},
"links": [
{
"rel": "self",
"type": "application/geo+json",
"href": "https://catalogue.demo.apex.esa.int/collections/esa-worldsoils/items/europe_aggr-orgc_00-020_mean_100_202003-202210"
},
{
"rel": "parent",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/collections/esa-worldsoils"
},
{
"rel": "collection",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/collections/esa-worldsoils"
},
{
"rel": "root",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
}
],
"assets": {
"SOC": {
"href": "https://eoresults.esa.int/d/APEX_TEST/2020/03/01/europe_aggr-orgc_00-020_mean_100_202003-202210/europe_aggr-orgc_00-020_mean_100_202003-202210.tif",
"type": "image/tiff; application=geotiff",
"roles": [
"data"
]
}
}
}
],
"links": [
{
"rel": "root",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/"
},
{
"rel": "self",
"type": "application/json",
"href": "https://catalogue.demo.apex.esa.int/collections/esa-worldsoils/items"
}
],
"numReturned": 1,
"numMatched": 1
}
Visualizing in the APEx STAC Browser
The APEx product catalogue includes a STAC browser that enables you to visually explore collections and items. You can access the browser at the following URL: browser.<project>.apex.esa.int
.
Cleaning Up
Once the demo is complete, we can easily clean up by deleting the test collection, which is no longer needed.
f"{CATALOGUE}/collections/" + collection.id, auth=auth) requests.delete(
<Response [204]>