11
22import logging
3+ import os
4+ import openeo
5+ import re
6+
7+ import urllib
8+
9+ import requests
310
411from app .platforms .base import BaseProcessingPlatform
5- from app .schemas import ProcessingJobSummary
12+ from app .schemas import ProcessingJobSummary , ProcessingStatusEnum , ServiceDetails
13+
14+ from dotenv import load_dotenv
615
16+ load_dotenv ()
717
818logger = logging .getLogger (__name__ )
919
@@ -12,14 +22,98 @@ class OpenEOPlatform(BaseProcessingPlatform):
1222 OpenEO processing platform implementation.
1323 This class handles the execution of processing jobs on the OpenEO platform.
1424 """
25+
26+ def _setup_connection (self , url : str ) -> None :
27+ """
28+ Setup the connection to the OpenEO backend.
29+ This method can be used to initialize any required client or session.
30+ """
31+ logger .debug (f"Setting up OpenEO connection to { url } " )
32+ connection = openeo .connect (url )
33+ provider_id , client_id , client_secret = self ._get_client_credentials (url )
34+
35+ connection .authenticate_oidc_device ()
36+
37+ # connection.authenticate_oidc_client_credentials(
38+ # provider_id=provider_id,
39+ # client_id=client_id,
40+ # client_secret=client_secret,
41+ # )
42+ return connection
43+
44+ def _get_client_credentials (self , url : str ) -> tuple [str , str , str ]:
45+ """
46+ Get client credentials for the OpenEO backend.
47+ This method retrieves the client credentials from environment variables.
48+
49+ :param url: The URL of the OpenEO backend.
50+ :return: A tuple containing provider ID, client ID, and client secret.
51+ """
52+ auth_env_var = self ._get_client_credentials_env_var (url )
53+ if auth_env_var not in os .environ :
54+ raise ValueError (f"Environment variable { auth_env_var } not set." )
55+
56+ client_credentials = os .environ [auth_env_var ]
57+ return client_credentials .split ("/" , 2 )
58+
59+ def _get_client_credentials_env_var (self , url : str ) -> str :
60+ """
61+ Get client credentials env var name for a given backend URL.
62+ """
63+ if not re .match (r"https?://" , url ):
64+ url = f"https://{ url } "
65+ parsed = urllib .parse .urlparse (url )
66+
67+ hostname = parsed .hostname
68+ if hostname in {
69+ "openeo.dataspace.copernicus.eu" ,
70+ "openeofed.dataspace.copernicus.eu" ,
71+ }:
72+ return "OPENEO_AUTH_CLIENT_CREDENTIALS_CDSEFED"
73+ else :
74+ raise ValueError (f"Unsupported backend: { url = } ({ hostname = } )" )
75+
76+ def _get_process_id (self , url : str ) -> str :
77+ """
78+ Get the process ID from a JSON file hosted at the given URL.
79+
80+ :param url: The URL of the JSON file.
81+ :return: The process ID extracted from the JSON file.
82+ """
83+ logger .debug (f"Fetching process ID from { url } " )
84+ response = requests .get (url ).json ()
85+ return response .get ("id" )
1586
16- def execute_job (self , service_id : str , parameters : dict ) -> ProcessingJobSummary :
87+ def execute_job (self , title : str , details : ServiceDetails , parameters : dict ) -> ProcessingJobSummary :
1788 """
1889 Execute a processing job on the OpenEO platform with the given service ID and parameters.
1990
20- :param service_id: The ID of the service to execute.
91+ :param title: The title of the job to be executed.
92+ :param details: The service details containing the service ID and application.
2193 :param parameters: The parameters required for the job execution.
2294 :return: A ProcessingJobSummary object containing the job details.
2395 """
24- logger .debug (f"Executing OpenEO job with service_id={ service_id } and parameters={ parameters } " )
25- raise NotImplementedError ("OpenEO job execution not implemented yet." )
96+
97+ try :
98+ process_id = self ._get_process_id (details .application )
99+ if not process_id :
100+ raise ValueError (f"Process ID not found for service: { details .service } " )
101+
102+ logger .debug (f"Executing OpenEO job with title={ title } , service={ details } , process_id={ process_id } and parameters={ parameters } " )
103+ connection = self ._setup_connection (details .service )
104+ service = connection .datacube_from_process (
105+ process_id = process_id ,
106+ namespace = details .application ,
107+ ** parameters
108+ )
109+ job = service .create_job (title = title )
110+ job .start ()
111+
112+ return ProcessingJobSummary (
113+ id = job .job_id ,
114+ title = title ,
115+ status = ProcessingStatusEnum .CREATED
116+ )
117+ except Exception as e :
118+ logger .exception (f"Failed to execute openEO job: { e } " )
119+ raise Exception ("Failed to execute openEO job" )
0 commit comments