Introduction

The JS7 - REST Web Service API allows performing any sort of operation on the lifecycle of scheduling objects such as creating, deploying, running, stopping workflows and jobs.

The REST Web Service API is available from JOC Cockpit. Use of the REST Web Service API requires jobs to implement a REST Client for the functionality to login and to logout from JOC Cockpit and any other calls to the API.

In order to reduce the overhead of REST Client implementation, a Python class is suggested for simplified use of the JS7 REST Web Service by jobs using Oracle® GraalVM, see JS7 - GraalVM Python Jobs.

FEATURE AVAILABILITY STARTING FROM RELEASE 2.8.2

REST Client Python Class

A Python class is suggested that

  • connects to JOC Cockpit and performs login to JOC Cockpit for access to the JS7 REST Web Service API using
    • ApiExecutor = java.type("com.sos.js7.job.jocapi.ApiExecutor")
  • performs calls to the JS7 REST Web Service API from the method
    • post(path, body)

For re-usability users can add the Python class to a JS7 - Script Include that can be used by any number of jobs. Changes to the Script Include will be reflected with the next deployment of the workflow.

Download Python class from Script Include (upload .json): Python-JS7RestApi.includescript.json


Find the source code of the REST Client Python class:

  • The Python class makes use of the Java ApiExecutor class that ships with JS7 Agents.
  • The class automatically signs in to JOC Cockpit from its constructor.
    • The JOC Cockpit URL, user account, password or certificate are used from the JS7 Agent's ./config/private/private.conf file.
    • For details see JS7 - JITL Common Authentication
  • The class automatically signs off from JOC Cockpit by use of its destructor.

Example of a Python class for access to the JS7 REST Web Service API
import java
ApiExecutor = java.type("com.sos.js7.job.jocapi.ApiExecutor")

class JS7RestApi:
    def __init__(self, js7Step):
        self.module_name = "Python-JS7RestApi"
        self.logger = js7Step.getLogger()
        self.api_executor = ApiExecutor(js7Step)
        self.access_token = None
        
        try:
            self.access_token = self.api_executor.login().getAccessToken()
        except Exception as e:
            self.close()            
            raise e

    def __enter__(self):
        return self
            
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
      
    def close(self):
        if self.logger.isDebugEnabled():
            self.logger.debug(f"[{self.module_name}]close")

        if self.api_executor is not None:
            self.api_executor.closeQuietly(self.access_token)

        self.api_executor = None
        self.access_token = None

    def post(self, path, body):
        response = self.api_executor.post(self.access_token, path, body)
        if self.logger.isDebugEnabled():
            self.logger.debug(f"[{self.module_name}][{response.getStatusCode()}]{response.getResponseBody()}")
       
        return response

Python Job

A Python job can make use of the REST Client Python class provided by the Script Include:

  • The following syntax makes the Python class available from a Script Include:
    • ##!include Python-JS7RestApi
  • The Python class can be instantiated by the job like this:
    • ApiExecutor = java.type("com.sos.js7.job.jocapi.ApiExecutor")
    • For use of the js7Step object see JS7 - Job API.

Download sample Python job from Workflow (upload .json): pdPythonJS7RestAPI.workflow.json


Find the source code of the job script:

Example of job script using JavaScript class to access the JS7 REST Web Service API
import json

##!include Python-JS7RestApi
class JS7Job(js7.Job):
    def processOrder(self, js7Step):
        logger = js7Step.getLogger()
        
        with JS7RestApi(js7Step) as api:
            controller_id = js7Step.getControllerId()
            body = json.dumps({"controllerId": controller_id})
        
            response = api.post("/joc/api/authentication/joc_cockpit_permissions", body)
            logger.info(f"response body: {response.getResponseBody()}")
            logger.info(f"response status code: {response.getStatusCode()}")


Explanation:

  • Line 1: references the Script Include to make the REST API Python class available.
  • Line 3,5: implement the Python job.
  • Line 7: creates an instance of the REST Client Python class that implicitly signs in to JOC Cockpit.
  • Line 9: executes a call to the JS7 REST Web Service that returns the current user's permissions in JOC Cockpit from the REST response.
  • Line 10,11: include examples for use of methods to retrieve the response body and HTTP status code.
  • Line 13,14: parses the JSON response body to access properties in the response.
  • Line 16: destructs the instance and implicitly signs out from JOC Cockpit.

Resources