Algorithm of the Python Framework#

The Python framework script, launched via the Windows Scheduler, must follow the following algorithm:

  1. Perform an HTTP POST request to the /api/robot/heartbeat script of the Orchestrator. Pass the following parameters:
    1. The GUID of this Robot (RobotGUID),
    2. The name of the computer (Machine),
    3. The IP address of the machine (IP),
    4. The MAC address of the machine (MAC),
    5. The current status of the Robot (Status),
    6. The GUID of the currently executing Job (JobGUID),
    7. The name of the currently executing Job (JobName),
    8. The type of Job (JobType, must always be of type Orchestrated, value 1).

Output data (in JSON format):

  • HeartbeatErrorCode,
  • ErrorText,
  • HasNewJob.

The script may return other parameters in the response that are not used in the context of the current Task.

Robot status reference:

Status_Disconnected = 0; # robot is disconnected
Status_Unlicensed     = 1; # robot is unlicensed
Status_Ready        = 2; # robot is not performing jobs and is ready to accept new jobs
Status_Working    = 3; # robot is performing the current job

ErrorCode values reference:

HeartbeatErrorCode_NoError = 0;  # no errors
HeartbeatErrorCode_RobotNotFound = 101;  # robot with the specified GUID not found
HeartbeatErrorCode_JobAborting = 10;   # the orchestrator requested a hard stop of this script (Abort)
HeartbeatErrorCode_JobStopping = 20;   # the orchestrator requested a soft stop of this script (Stop)

HasNewJob values reference:

HasNewJob_NoJob = 0 # there are no new jobs for this robot
HasNewJob_JobFound = 1 # there are new jobs for this robot that need to be retrieved using the ConsumeNextJob call

When the script is first run, it is necessary to pass the value Status = 2 (Status_Ready). Also, during the first run, when the name and GUID of the executing job are still unknown, these fields may remain empty.

Example call:

import requests
import base64
import json

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
host = 'http://192.168.1.111:4500' #orchestrator host
robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #robot GUID
headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
}
req = {
    'RobotGUID': robot_guid,   #robot GUID
    'Machine': robot_machine,   #Machine name
    'IP': robot_ip,   #Robot IP address
    'MAC': robot_mac,   #Robot MAC address
    'Status': 2,   #robot status
    'JobGUID': '',  #Job GUID
    'JobName': '',   #name of the executing script, i.e., python_script_name hereafter
    'JobType': 1   #job type, always value 1
}
r = requests.post(host + '/api/robot/heartbeat', data=req, headers=headers, verify=False)
heartbeat_results = json.loads(r.text)
print(heartbeat_results['HeartbeatErrorCode'])
print(heartbeat_results['ErrorText'])
print(heartbeat_results['HasNewJob'])
  1. If the response is HasNewJob == 0, terminate the execution of the framework script and log off from the Windows account using Log off.

    If the response is HasNewJob == 1, perform an HTTP POST request to the /api/robot/consumeNextJob script of the Orchestrator.

    Input data:

    1. Robot GUID (RobotGUID),
    2. Current status of the Robot (Status).


    Output data (in JSON format):

    1. ConsumeJobErrorCode,
    2. ErrorText,
    3. Job,
    4. ProcessVersion,
    5. Task.

    ConsumeJobErrorCode values reference:

    ConsumeJobErrorCode = 0; # no errors
    ConsumeJobErrorCode = 101; # robot with the specified GUID not found
    ConsumeJobErrorCode = 102; # new job not found

    Example call:

    import requests
    import base64
    import json

    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

    host = 'http://192.168.1.111:4500' #orchestrator host
    robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #robot GUID

    headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
    }

    cnj = {
    'RobotGUID': robot_guid #robot GUID
    }

    r = requests.post(host + '/api/robot/consumeNextJob', data=cnj, headers=headers, verify=False)
    consume_result = json.loads(r.text)
    print(consume_result['ConsumeJobErrorCode'])
    print(consume_result['ErrorText'])
    new_job = json.loads(consume_result['Job'])
    job_guid = new_job['GUID']
    process_version = json.loads(consume_result['ProcessVersion'])
    python_script_name = process_version['Name'] #Assuming that the name of the robot script to be executed is passed in the process version name
    task = json.loads(consume_result[' Task '])

  2. In case of successfully receiving a new Job from the Orchestrator, perform an HTTP PUT request to the /api/job/update script of the Orchestrator. Pass the GUID of the received Job (guid) and the new Job status Status_In_Progress.

    Job status values reference:

    Status_Created = 0; #Job created
    Status_Pending = 1; #Job is waiting for the robot to take it on
    Status_Aborting = 2; #Job is in the process of hard stopping (interrupting)
    Status_Aborted = 3; #Job has been successfully interrupted
    Status_Success = 4; #Job has been successfully completed
    Status_Failed = 5; #Job has not been successfully completed
    Status_Stopping = 6; #Job is in the process of soft stopping
    Status_Stopped = 7; #Job has been successfully stopped after a soft stop request
    Status_In_Progress = 8; #Job is currently being executed

    Example call:

    import requests
    import base64
    import json

    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    host = 'http://192.168.1.111:4500' #orchestrator host
    robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #robot GUID

    headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
    }

    job = {
    'guid': job_guid, #GUID of the current job
    'status': 8 #new job status
    }

    r = requests.put(host + '/api/job/update', data=job, headers=headers, verify=False)
    print(r.text)

  3. Start executing the Python script of the Robot with the name equal to python_script_name. If possible, periodically repeat requests to the /api/robot/heartbeat script with the correct values for JobGUID and Status = 3 (Status_Working).

    It is recommended to send this request no more than once every 10 seconds. If the response status is HeartbeatErrorCode == 10, immediately stop (abort) the execution of the Python script of the Robot.

    If the response status is HeartbeatErrorCode == 20, perform a proper termination of the Python script of the Robot.

  4. After the completion of the Python script of the Robot, perform an HTTP PUT request to the /api/job/update script of the Orchestrator. Pass the GUID of the current Job of the Robot (guid) and the new Job status depending on the result of its completion according to the reference provided above.

  5. Then perform an HTTP POST request to the /api/robot/heartbeat script of the Orchestrator with the status Status = 2 (Status_Ready) and return to step 2 of the framework algorithm.