Python automations and script runners
Python automations and script runners

Python automations and script runners

1. Overview

In order to run python scripts, KAWA relies on script runners.

KAWA has a per workspace script runner configuration:

image

This means that each workspace can communicate with its own instance of a script runner.

📌
In order to access all python related features in a given workspace, a script runner should be configured for it.

In order to see if an active runner is attached to a workspace:

image

2. Configure a script runner

Configuring a script runner for a workspace requires two steps:

  • Start an instance of a KAWA script runner (This step can be skipped if you decide to reuse an existing instance)
  • Connect the runner into your workspace (Requires admin privileges)

2. a) Start a script runner

  1. Generate a secret

The first thing to do is generate an AES key for your instance. This key will be shared between the script runner and KAWA (It should not be communicated anywhere else). It will prevent principals without the key to be able to run any script on the KAWA script runner.

Below an example on how to generate a secure random AES key. We require a size of 32 octets.

head /dev/urandom | shasum -a 256 | cut -d ' ' -f 1 > kawa-runner.key
chmod 600 kawa-runner.key

Example of a valid key: 161ea26cc7e989534d6d965912174c68e654f2b716d3407c7ee9b0db96625689

  1. Make sure you have the latest version of KAWA’s Python library

It is recommended to work from a python virtual environment to run this installation.

Download the latest version of KAWA Python module:

pip install kywy --upgrade --extra-index-url https://kawa:Br2zFU2Y5EGBWr4khYzh@gitlab.com/api/v4/projects/31007056/packages/pypi/simple
  1. Start the script runner

Supposing that the private key is stored in kawa-runner.key, run the following command:

kawa-automation-server $(cat kawa-runner.key)

Further configuration is available through environment variables:

variable name
default value
description
KAWA_AUTOMATION_SERVER_HOST
0.0.0.0
Binds the server to this host address
KAWA_AUTOMATION_SERVER_PORT
8815
Binds the server to this port
KAWA_AUTOMATION_SERVER_USER_TLS
false
Set to true to enable TLS between KAWA and the Script runner
KAWA_AUTOMATION_SERVER_TLS_CERT_PATH
empty
If TLS is enabled, we require the path to a certificate file
KAWA_AUTOMATION_SERVER_TLS_KEY_PATH
empty
If TLS is enabled, we require the path to the matching private key file
KAWA_AUTOMATION_SERVER_WORKING_DIRECTORY
/tmp
Path to directory that contains temporary data

⚠️ It is recommended to start this server as a service on your System.

📌
Being executed from within a venv, the script runner will have access to all the python modules that are installed in that venv. Make sure that all the required dependencies for your scripts are installed within that venv.

2. b) Register the runner in a workspace

Once that you have a started runner, you can register it in as many KAWA workspaces as you wish.

This can be done using the KAWA Python client:

from kywy.client.kawa_client import KawaClient

# Connect to your KAWA instance
kawa = KawaClient(kawa_api_url='https://<YOUR URL>')
kawa.set_api_key(api_key_file='<PATH TO THE KEY FILE>')

# Connect to the workspace you want to connect this runner to
kawa.set_active_workspace_id(workspace_id=1)
cmd = kawa.commands

# Register the runner
# The private_key parameter should contain your AES key, generated above.
cmd.add_script_runner(
    name='Main runner',
    host='localhost',
    port=8815,
    tls=False,
    # This is optional. It is not needed when the system was setup
    # With a default AES key, shared between a runner and the server.
    private_key='<your AES key>'
)

# If the configuration is correct, you should 
# see something similar to this:
# {
#	   'systemProperties': {'uri': 'grpc+tcp://localhost:8815'}, 
#    'healthy': True, 
#    'information': ''
# }
print(kawa.runner_health())

Once this step is complete, you can check that the Script runner is activated in your workspace.

2. c) Change runner configuration

Log into the workspace in which you wish to change the runner configuration (cf above):

Toggling a runner on and off:

cmd.toggle_script_runner(enabled=False)

Changing the runner configuration:

cmd.replace_script_runner_private_key(private_key='<your AES key>')
cmd.replace_script_runner_location(host='local', port=123, tls=False)

3. Create an automation to send charts to Slack

Here is a simple example to send a chart generated from KAWA data into the Slack messaging platform. This can be adapted to your own messaging platform or APIs.

image
image

3. a) Prerequisites

Before you start, make sure that your workspace has python support turned on.

image

Make sure that you have configured a Slack App in your workspace and that you have a Bot User OAuth Token with the following scope (cf this guide to get you started on that: https://api.slack.com/tutorials/tracks/getting-a-token):

image

3. b) Create your KAWA automation

Let’s start from the E-commerce data sample. From the data section, click on start next to this data sample as shown below, and then navigate to the newly created sheet.

image

Next, create a new automation:

image

STEP1: Setup your trigger

Have your automation run on data refresh, so that it will automatically run each time the data is refreshed.

image

STEP2: Setup your data

Then, let’s configure a simple view to send:

1) Hide all fields except State and Profit

2) Group by State

3) Keep the top ten state per profit

image

STEP3: Write your Python script

Choose script on the top section and copy an paste the following script into the python editor:

from kywy.server import kawa_automation as kawa
# Make sure to pip install slack_sdk inside the script runner
from slack_sdk import WebClient
import uuid
import os

# This is the slack channel you will send your data to
# refer to this doc https://api.slack.com/methods/conversations.list
# to undertsand how to retrieve your channel id from a channel name.
SLACK_CHANNEL_ID='C0642K8FHJ6'

class AutomationScript(kawa.BaseAutomationScript):

    def metadata(self):
      return {
         'parameters': [
             {'name': 'state', 'type': kawa.Types.TEXT},
             {'name': 'profit', 'type': kawa.Types.INTEGER}
         ]
      }
     
    def execute(self, data: kawa.AutomationData):
      file_name='/tmp/test-{}.png'.format(uuid.uuid4())
      df = data.to_pandas()
      message = 'Profit by state for the top {} states :bar_chart:'.format(df.shape[0])

      try:
        self.generate_chart(file_name, df)
        self.send_to_slack(file_name,message)
      finally:
        os.remove(file_name)

    def generate_chart(self, file_name, df):
       chart = df.plot(x='state', y='profit', kind='bar', alpha=0.75, rot=20).get_figure()
       chart.savefig(file_name)

    def send_to_slack(self, file_name, message):
      client = WebClient(token=SCRIPT_SECRET)
      client.files_upload(
          channels=SLACK_CHANNEL_ID,
          initial_comment=message,
          file=file_name,
          filename='Chart'
      )

Then click on Generate and configure the right section:

  • Bindings the state and profit inputs
  • Copy and paste your Bot User OAuth token in the script secret input.
image

STEP4: Save and run your script

Choose a name for your script (input is at the top of the automation screen) and Save.

You can run your automation manually from there:

image

Or just refresh you data, from the datasource section, to trigger it.