In this demo, we will demonstrate how to ingest project-generated data into the APEx product catalogue. The process will include:
1. Generating Data with openEO We will generate Sentinel-2 (S2) imagery over Gran Canaria using openEO. This data will be used to simulate project-generated data that can be ingested into the APEx catalogue.
2. Ingesting the Data into the APEx STAC Catalogue After generating the data, we will show how to ingest it into the APEx STAC catalogue. This will allow the data to be stored in a standardized format for discovery and access.
3. Visualizing the Result in the STAC Browser Once the data is ingested, we will use the STAC browser to visualize the product and verify its availability in the catalogue.
Requirement already satisfied: openeo in /opt/conda/lib/python3.11/site-packages (0.35.0)
Requirement already satisfied: owslib in /opt/conda/lib/python3.11/site-packages (0.32.0)
Requirement already satisfied: requests_oauthlib in /opt/conda/lib/python3.11/site-packages (2.0.0)
Requirement already satisfied: requests>=2.26.0 in /opt/conda/lib/python3.11/site-packages (from openeo) (2.32.3)
Requirement already satisfied: shapely>=1.6.4 in /opt/conda/lib/python3.11/site-packages (from openeo) (2.0.6)
Requirement already satisfied: numpy>=1.17.0 in /opt/conda/lib/python3.11/site-packages (from openeo) (2.2.0)
Requirement already satisfied: xarray>=0.12.3 in /opt/conda/lib/python3.11/site-packages (from openeo) (2024.11.0)
Requirement already satisfied: pandas>0.20.0 in /opt/conda/lib/python3.11/site-packages (from openeo) (2.2.3)
Requirement already satisfied: pystac>=1.5.0 in /opt/conda/lib/python3.11/site-packages (from openeo) (1.11.0)
Requirement already satisfied: deprecated>=1.2.12 in /opt/conda/lib/python3.11/site-packages (from openeo) (1.2.15)
Requirement already satisfied: lxml in /opt/conda/lib/python3.11/site-packages (from owslib) (5.3.0)
Requirement already satisfied: python-dateutil in /opt/conda/lib/python3.11/site-packages (from owslib) (2.9.0)
Requirement already satisfied: pyyaml in /opt/conda/lib/python3.11/site-packages (from owslib) (6.0.2)
Requirement already satisfied: oauthlib>=3.0.0 in /opt/conda/lib/python3.11/site-packages (from requests_oauthlib) (3.2.2)
Requirement already satisfied: wrapt<2,>=1.10 in /opt/conda/lib/python3.11/site-packages (from deprecated>=1.2.12->openeo) (1.17.0)
Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.11/site-packages (from pandas>0.20.0->openeo) (2024.2)
Requirement already satisfied: tzdata>=2022.7 in /opt/conda/lib/python3.11/site-packages (from pandas>0.20.0->openeo) (2024.2)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.11/site-packages (from python-dateutil->owslib) (1.16.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /opt/conda/lib/python3.11/site-packages (from requests>=2.26.0->openeo) (3.4.0)
Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.11/site-packages (from requests>=2.26.0->openeo) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.11/site-packages (from requests>=2.26.0->openeo) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.11/site-packages (from requests>=2.26.0->openeo) (2024.8.30)
Requirement already satisfied: packaging>=23.2 in /opt/conda/lib/python3.11/site-packages (from xarray>=0.12.3->openeo) (24.1)
1. Generating Data with openEO
In this section, we will use openEO to generate some Earth observation data, which we will later ingest into the catalogue. Specifically, we will generate a Sentinel-2 image over the Gran Canaria region. The result of this step is a gran_canaria.tiff that is downloaded locally.
import openeobounds = (-28.30438068296276, -16.171874999999993, -27.68352808378777, -15.468750000000012)resolution =38.21851414258813con = openeo.connect("openeo.dataspace.copernicus.eu").authenticate_oidc()cube = con.load_collection("SENTINEL2_L2A", bands=["B04"], temporal_extent="2019-08-19", spatial_extent={"west": bounds[1],"south": abs(bounds[2]),#abs is weird, does GlobalMercator return wrong latitude values?"east": bounds[3],"north": abs(bounds[0]), })cube.result_node().update_arguments(featureflags={"tilesize": 256})#force block size in output tiffresult = cube.resample_spatial(resolution=resolution,projection="EPSG:3857")job = result.execute_batch("gran_canaria.tiff",title="APEx - Demo - Gran Canaria",filename_prefix="gran_canaria")
2. Ingesting the Data into the APEx STAC Catalogue
In this section we explore how to use the generated openEO result to generate STAC metadata. This STAC metadata is then used to ingest the result into the project’s STAC catalogue.
In this section, we demonstrate how to use the generated openEO results to create STAC metadata. This metadata is then utilized to ingest the results into the project’s STAC catalogue.
import pystac
stac_metadata_dict = job.get_results().get_metadata()stac_metadata_dict["id"] = STAC_METADATA_ID#remove collection assets, we will rely on item linksdel stac_metadata_dict["assets"]collection = pystac.Collection.from_dict(stac_metadata_dict)collection
type"Collection"
id"gran_canaria_demo"
stac_version"1.0.0"
description"Results for batch job j-241209296c304e40aab094e29220d448"
description"This data was processed on an openEO backend maintained by VITO."
roles[] 1 items
0"processor"
processing:expression
expression
loadcollection1
arguments
bands[] 1 items
0"B04"
featureflags
tilesize256
id"SENTINEL2_L2A"
spatial_extent
east-15.468750000000012
north28.30438068296276
south27.68352808378777
west-16.171874999999993
temporal_extent[] 2 items
0"2019-08-19"
1"2019-08-20"
process_id"load_collection"
resamplespatial1
arguments
align"upper-left"
data
from_node"loadcollection1"
method"near"
projection"EPSG:3857"
resolution38.21851414258813
process_id"resample_spatial"
saveresult1
arguments
data
from_node"resamplespatial1"
format"GTiff"
options
filename_prefix"gran_canaria"
process_id"save_result"
resultTrue
format"openeo"
processing:facility"openEO Geotrellis backend"
processing:software
Geotrellis backend"0.50.1a1"
2.3. Authenticate with STAC API
In this step, we will authenticate with the STAC catalogue for our project. The code leverages an external library, called requests_oauthlib, to handle the authentication process and retrieve the access token. Obtaining this token is a necessary prerequisite for performing the data ingestion step.
After opening the URL in your webbrowser, you will need to copy paste the resulting URL in the input field provided by the next cell.
from requests_oauthlib import OAuth2Sessionimport webbrowser
SERVER_URL ="https://auth.apex.esa.int/"REALM ="apex"CLIENT_ID ="demo-catalogue-dev-api"REDIRECT_URI =f"{CATALOGUE_URL}/callback"BASE_URL =f"{SERVER_URL}/realms/{REALM}/protocol/openid-connect"AUTHORIZATION_URL =f"{BASE_URL}/auth"TOKEN_URL =f"{BASE_URL}/token"# Initialize OAuth2 sessionoauth = OAuth2Session( client_id=CLIENT_ID, redirect_uri=REDIRECT_URI)# Step 1: Generate the authorization URLauthorization_url, state = oauth.authorization_url(AUTHORIZATION_URL)print(f"Visit this URL to authorize the application: {authorization_url}")# Step 2: Paste the redirect URL after loginredirect_response =input("Paste the full redirect URL here: ")# Step 3: Exchange the authorization code for an access tokentry: token = oauth.fetch_token( TOKEN_URL, authorization_response=redirect_response, ) access_token = token["access_token"]exceptExceptionas e:print(f"Error fetching token: {e}")access_token
Visit this URL to authorize the application: https://auth.apex.esa.int//realms/apex/protocol/openid-connect/auth?response_type=code&client_id=demo-catalogue-dev-api&redirect_uri=https%3A%2F%2Fcatalogue.demo.apex.esa.int%2Fcallback&state=plQHbFFL4TpynvLEmM7RMpp7UJuB5o
Paste the full redirect URL here: https://catalogue.demo.apex.esa.int/callback?state=plQHbFFL4TpynvLEmM7RMpp7UJuB5o&session_state=a13c63ff-049c-44d0-bd4d-46566729a8be&iss=https%3A%2F%2Fauth.apex.esa.int%2Frealms%2Fapex&code=db520cdb-18ea-4573-9e4b-fa14e0f56ebf.a13c63ff-049c-44d0-bd4d-46566729a8be.7f328923-c069-40b9-a30f-739450ad7703
The collection metadata has been cleaned and is now ready to be added to the STAC API. In this step, we are creating the full collection, but it’s also possible to add the generated item to a new collection if preferred.
Additionally, it’s recommended to enhance the metadata quality by adding extra metadata properties where applicable.
Important Note Currently, the Geotiff file is stored on the openEO backend and can be accessed through a signed URL. However, this URL will eventually expire. For more permanent cataloging, the data file should be moved to a more stable location. To do so, simply download the TIFF file and upload it to your preferred online storage location.