Skip to main content
System StatusContact Support
VersionOne Community

Continuum Canvas Widget Processors

Overview

An overview of the Processor Widgets, which are special type of widgets that leverage the full power of Python to manipulate data.

Assumptions

The reader should have a working knowledge of the Python programming language.

Hello World

Let's start by building a very simple 'hello world' processor Widget.

In the Canvas Editor, click the New Item button. In the dialog, enter tutorials as the Project, processor as the Component, and proc.widget as the Name. Click Save.

Paste the following code into the editor and click Save:

{
    "type": "processor",
    "options": {
        "processor": {
            "project": "tutorial",
            "component": "processor",
            "name": "proc.py"
}
}
}

This Widget definition simply points to a processor resource. Let's create that resource.

In the resource browser, click the + beside the component we created called processor. A prompt will appear - enter proc.pyinto the Name and click Save.

Paste the following in to the editor and click Save:

def main(**kwargs):
    return "hello world"

In the resource browser, select 'proc.widget' and click the Test button.

You cannot Test a processor resource - always change back to the parent Widget to click the Test button.

The test window should appear and say 'hello world'. Congratulations, you just made a Processor Widget!

Rules

A Processor has a few simple rules that must be followed, or errors will occur.

  • The main function definition must be def main(**kwargs):

  • Whatever processing happens, the processor must return a string - no other return types are permitted.

  • Of course, Python indenting rules must be followed.

Features

Canvas is part of the Continuum platform, and a few helper functions are available.

Writing Log Output

The Canvas logger can be accessed within a processor. It's a standard Python logger, supporting .debug.info.warning.error, and .critical.

To write into the log file:

canvas.logger.critical("this is a log entry")

Looking into the Session

While you can access the Session directly, a helper method exists as well. To pull a value out of the Session:

x = canvas.lookup_var("foo", kwargs["session"])
return x

The canvas.lookup_var function is helpful, because Session can contain very complex structures. lookup_var utilizes Python eval rules for evaluating the expression against the Session. Use of the Widget feature to set results into the Session will almost always result in a complex Session.

For example:

x = canvas.lookup_var('my_array[3]["item"].get("name")', kwargs["session"])
return x

would look into the Session for the 4th item in 'my_array', find the 'item' property on that object and get the 'name'.

Standard Arguments

The 'main' function definition accepts an arguments dictionary - **kwargs.

Individual arguments can be accessed as follows for example to set d to the Widget data:

d = kwargs["data"]

kwargs contains the following properties:

  • data - If the Widget had a Datasource definition and a Code option, results are available.

  • session - The complete Session for this Widget.

  • args - Any additional arguments provided as 'args' in the 'processor' option of the widget.

  • options - The Widget Options

  • datasource - The Widget Datasource

Advanced Example

Here is an example of a Processor that generates JSON data about host uptime, suitable for a Flot chart.

This example assumes a running Deployment in Deploy, with associated Hosts.

In the Canvas Editor, click the New Item button. In the dialog, enter tutorials as the Project, processor as the Component, and advanced.widget as the Name. Click Save.

Paste the following code into the editor and click Save:

{
    "type": "processor",
    "options": {
        "processor": {
            "project": "tutorial",
            "component": "processor",
            "name": "advanced.py"
        }
    },
    "datasource": {
        "name": "_CATO"
    },
    "code" : [
        "select cast(dh.host_name as char(12)) as host_name,",
        " ifnull((unix_timestamp(now()) - unix_timestamp(dh.up_dt)) / 3600, 0) as uptime",
        " from deployment_host dh",
        " join deployment_service_inst dsi on dh.host_id = dsi.host_id",
        " limit 1"]
}

Obviously this Widget could be enhanced to pick a specific Instance, instead of just a random one.

In the resource browser, click the + beside the component we created called processor. A prompt will appear - enter advanced.py into the Name and click Save.

Paste the following in to the editor and click Save:

import json

def main(**kwargs):
    """
    Returns Flot friendly data json representing host uptime.
    """
    session = kwargs["session"]
    rows = kwargs["data"]

    data = []
    ticks = []

    # work the rows
    if rows:
        i = 0
        for row in rows:
            data.append({"data": [[i, row["uptime"]]]})
            ticks.append([i, row["host_name"]])
            i += 1

        # for this bar chart we're returning flot options as well
        out = {}
        out["ticks"] = ticks
        out["data"] = data

        return json.dumps(out, sort_keys=True, indent=4, default=canvas.jsonSerializeHandler)
    else:
        canvas.logger.warning("Provided data is empty.")

    return "[]"

Select the 'advanced.widget' in the resource browser and click Test. Congratulations, you've built an advanced Processor Widget!

The data returned by this widget Would be requested by a Layout that includes the necessary javascript to push this data into a client side charting tool such as Flot.

  • Was this article helpful?