ccp.docs/source/usermanual/07_rest_api.md

3.5 KiB

REST APIs: Interacting with Methods and Executions programmatically

Most of the services that build up CCP are accessible programmatically via REST endpoints. In particular, listing Methods (Jobs), executing them or getting infromation on running executions (jobStatus) are accessible through a standard API defined by OGC (Open Geospatial Consortium). The REST API is Processes 1.2 described at https://ogcapi.ogc.org/processes/ and can be considered a modern rework of the former WPS spcification.

The CCP REST API is documented as OpenAPI 3 specification at https://app.swaggerhub.com/apis/OGC/ogcapi-processes-1-example-1/1.0.0 .

Through the code generation widgets available in the UI elements described above, it is possible to obtain stubs that show how to interact programmatically with CCP in order to request a Method execution or re-execution and to monitor the evolution.

The following is an example code stub generated for the R programming language.

Example code for requesting a Method execution on CCP

# Dependencies
library(httr)
library(jsonlite)
library(rstudioapi)

# Init
user = 'usrname'
context = 'a vre'
auth_ep = 'https://authep'
client_id = 'aclietnid'
ccp_ep = 'https://ccpep'

getToken <- function() {
  #login
  res = POST(auth_ep, body=list('grant_type'='password', 'client_id'=client_id, 'username'=user, 'password'=pwd), encode=c('form'), add_headers(c('Content-Type' = 'application/x-www-form-urlencoded')))
  tok = fromJSON(content(res, 'text'))
  #authorize
  res = POST(auth_ep, body=list('grant_type'='urn:ietf:params:oauth:grant-type:uma-ticket', 'audience'=context), encode=c('form'), add_headers(c('Content-Type' = 'application/x-www-form-urlencoded', 'Authorization' = paste('Bearer', tok['access_token'], sep=' '))))
  jwt = fromJSON(content(res, 'text'))['access_token']
  
  return (jwt)
}

# request in JSON
request = fromJSON('{
  "inputs":{
    "ccpimage":"bash",
    "ccpreplicas":"1"
  },
  "outputs":{
    "output":{
      "transmissionMode":"value"
    }
  },
  "response":"raw"
}')

# Auth code
pwd = askForPassword('Password to login')
jwt = getToken()

# Request Method execution
url = paste(ccp_ep, 'processes/{methodid}/execution', sep='/')
res = POST(url, body=request, encode = 'json', add_headers(c('Authorization' = paste('Bearer', jwt, sep=' '))))
if(status_code(res) == 201){
  jobStatus = fromJSON(content(res, 'text'))
}else{
  stop(paste('Unable to start execution:', content(res, 'text')))
}

# Poll for jobstatus
url = paste(ccp_ep, 'jobs', jobStatus['jobID'], sep='/')
while (jobStatus['status'] != 'successful' && jobStatus['status'] != 'failed'){
  print(paste('[',Sys.time(),']',jobStatus['status'],': ',jobStatus['message']))
  Sys.sleep(5)
  res = GET(url, add_headers(c('Authorization' = paste('Bearer', jwt, sep=' '))))
  if(status_code(res) == 200){
    jobStatus = fromJSON(content(res, 'text'))
  }else if(status_code(res) == 401){
    jwt = getToken()   
  }else{
    stop('Unable to poll for execution status')
  }
}

print(paste('[',Sys.time(),']',jobStatus['status'],': ',jobStatus['message']))
url = paste(ccp_ep, 'executions', jobStatus['jobID'], sep='/')
res = GET(url, add_headers(c('Accept' = 'application/json', 'Authorization' = paste('Bearer', jwt, sep=' '))))
print(fromJSON(content(res, 'text')))

url = paste(ccp_ep, 'executions', jobStatus['jobID'], 'outputs/output.zip', sep='/')
GET(url, add_headers(c('Accept' = 'application/json', 'Authorization' = paste('Bearer', jwt, sep=' '))), 
    write_disk('./output.zip', overwrite = FALSE))