Contents


An easy way to provision and invoke actions in IBM OpenWhisk

Introducing openWhiskLib.py, a tiny new Python library to simplify your use of this serverless computing platform

Comments

IBM OpenWhisk is a simple open source service that rapidly launches and runs code tidbits on-demand, in response to an incoming REST request. Check out the OpenWhisk beta offering on IBM Bluemix. In this tutorial, I first show you how to issue OpenWhisk commands manually. Then I show you how to use a Python library that I created to make it even easier to issue those commands.

I was eager to try OpenWhisk because I'd heard that it offers two big advantages: provisioning is really easy, and billing can be cheaper than running apps on a long-lived machine. After I figured out how to use OpenWhisk, I created and published a tiny Python library, openWhiskLib.py, to simplify these tasks (shown on the left of the figure below):

  • Provision JavaScript actions in OpenWhisk
  • Invoke the actions

Try OpenWhisk on BluemixGet openWhiskLib.py on GitHub

Diagram of two OpenWhisk actions
Diagram of two OpenWhisk actions

What you'll need for this tutorial

  • A Bluemix account. (Register for your free trial account or log in to Bluemix if you already have an account.)
  • A VM with Ubuntu Linux 14.04. (The steps in this tutorial refer to an Ubuntu Linux machine, but other operating systems should be similar.)
1

Set up an OpenWhisk client machine

Boot a VM with Ubuntu Linux 14.04, sign in as root, and apply its latest updates:

apt-get -y update ; apt-get -y dist-upgrade

You can now use this machine to upload the "Hello world" app to OpenWhisk as described in Step 3 below.

2

Install, configure, and test the OpenWhisk client

  1. Sign in to Bluemix and access the OpenWhisk CLI. On your screen, you now see three steps, with parameters customized for your Bluemix account.
  2. Perform the three steps on your OpenWhisk client machine:
    • Step 1: Download the OpenWhisk CLI, untar the file, and add the executable wsk to your path.
    • Step 2: wsk property set...

      This command writes your Bluemix credentials into a hidden file on your OpenWhisk client machine. For me, it created this hidden file in my home directory: .wskprops

      Hint: Save this hidden file. We'll use some of the parameters later in this tutorial for the environment variables for the Python library.

    • Step 3: wsk action invoke...

      This command communicates with the OpenWhisk service at Bluemix to confirm that your credentials work. After a few seconds, wsk responds with a JSON struct containing the word 'hello'. Success!

      For fun, change the message string from 'hello' to something else and repeat. The response should contain your new string.

Hint: Verbose Mode

If you add the -v parameter to any wsk command, it will show the HTTP request that it sent to the server. I found this feature very helpful for debugging and for discovering the parameters required to issue REST requests. (More details are in this Stack Overflow exchange.)

3

Upload an action file to the OpenWhisk service on Bluemix

A simple JavaScript snippet for an action file is available in the OpenWhisk tutorial on Bluemix.

  1. Issue the wsk commands shown in the tutorial to create, use, and delete the action file.
  2. Repeat the commands with the -v verbose option. This shows the REST request and parameters required to issue the commands from the command line.

    Here's an example:

    Create a file named 'hello.js' on your OpenWhisk client machine:

    function main() {
    return {payload: 'hello'};
    }
  3. Now issue the wsk command to upload the hello.js. Here's my command (with my user name and credentials obfuscated for privacy):
    wsk -v action create hello hello.js
    
    {'apihost': 'openwhisk.ng.bluemix.net', 'namespace': 'user@example.com_dev', 'clibuild': '2016-
    05-24T09:54:44-05:00', 'apiversion': 'v1'}
    ========
    REQUEST:
    PUT https://openwhisk.ng.bluemix.net/api/v1/namespaces/user
    %40example.com_dev/actions/hello
    Headers sent:
    {
         "Authorization": "Basic
    S3sjGo6dKeKSIIRENS135xOsT3jEs7IiS3sjGo6dKeKSIIRENS135xOsT3jEs7Ii",
         "Content-Type": "application/json"
    }
    Body sent:
    {"exec": {"kind": "nodejs", "code": "function main() {\n return {payload: 'hello'};\n}\n"}}

Notes:

  • The Auth string in the request header is different from the string that is stored in .wskprops. (I believe it is base 64-encoded.)
  • The content of hello.js is included in the request body in variable code as one long string.
4

Test the action

After creating the action, test it by issuing the wsk action invoke command:

wsk -v action invoke /whisk.system/samples/echo -p message hello --blocking --result
{'apihost': 'openwhisk.ng.bluemix.net', 'namespace': 'user@example.com_dev', 'clibuild': '2016-
05-24T09:54:44-05:00', 'apiversion': 'v1'}
========
REQUEST:
POST
https://openwhisk.ng.bluemix.net/api/v1/namespaces/whisk.system/actions/samples/echo?
blocking=true&result=true
Headers sent:
{
     "Authorization": "Basic
S3sjGo6dKeKSIIRENS135xOsT3jEs7IiS3sjGo6dKeKSIIRENS135xOsT3jEs7Ii",
     "Content-Type": "application/json"
}
Body sent:
{"message": "hello"}
--------
RESPONSE:
Got response with code 200
Body received:
{
  "message": "hello"
}
========
{
  "message": "hello"
}

Introducing openWhiskLib.py

Now that you've learned to issue all the commands manually, try using the new Python script to simplify issuing the commands.

To date, these functions have been developed and tested:

  • createAction(filename, action)
  • deleteAction(action)
  • invokeAction(action)
  • invokeEcho(message)
  • listActions()
  • listNamespaces()

The openWhiskLib project is publicly available on GitHub.

To use openWhiskLib on your machine, first define three environment variables:

OPENWHISK_APIHOST
Get this value from your file .wskprops
OPENWHISK_NAMESPACE
Get this value from your file .wskprops
OPENWHISK_TOKEN
Get this value from issuing any verbose wsk command, such as:
wsk -v action invoke /whisk.system/samples/echo -p message hello --blocking --result

For example, on your Linux laptop, you can set values like I did (my personal data is obscured for privacy):

export OPENWHISK_APIHOST="openwhisk.ng.bluemix.net"
export OPENWHISK_NAMESPACE="username@example.com_dev"
export
OPENWHISK_TOKEN="S3sjGo6dKeKSIIRENS135xOsT3jEs7IiS3sjGo6dKeKSIIRENS135xOsT3j
Es7Ii"

For convenience, you may define your values in a bash script. You can copy and edit this sample in the GitHub project: bin/setenv.sh

5

Use openWhiskLib.py to create actions

To create an action, first create a file on your machine containing a snippet of the JavaScript code that you want to be uploaded and executed. For example, you could use code similar to the same sample I listed above: goodday.js:

function main() {
     return {payload: 'good day'};
}

Then invoke the openWhiskLib function createAction() from your Python interpreter. For example:

Define environment variables (with a dot):

. setenv.sh

Invoke Python

python

Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> from openwhisklib import *
>>> createAction( 'goodday.js', 'goodday')
Issuing put request:
url=https://openwhisk.ng.bluemix.net/api/v1/namespaces/user@example.com_dev/actions/goodday
payload: {'exec': {'kind': 'nodejs', 'code': "function main() {\n return {payload: 'good day'};\n}\n"}}
headers={'content-type': 'application/json', 'Authorization': 'Basic
S3sjGo6dKeKSIIRENS135xOsT3jEs7IiS3sjGo6dKeKSIIRENS135xOsT3jEs7Ii'}
Response status_code=200
{
  "name": "goodday",
  "publish": false,
  "annotations": [],
  "version": "0.0.1",
  "exec": {
    "kind": "nodejs",
    "code": "function main() {\n return {payload: 'good day'};\n}\n"
},
"parameters": [],
limits": {
  "timeout": 60000,
  "memory": 256
},
"namespace": "user@example.com_dev"
}
<Response [200]>
>>>
6

Use openWhiskLib.py to invoke actions

And finally, invoke the code snippet from OpenWhisk at Bluemix using openWhiskLib.py:

>>>
>>> invokeAction('goodday')
Issuing request:
url=https://openwhisk.ng.bluemix.net/api/v1/namespaces/user@example.com_dev/actions/goodday?
blocking=true&result=false payload={} headers={'content-type': 'application/json', 'Authorization':
'Basic S3sjGo6dKeKSIIRENS135xOsT3jEs7IiS3sjGo6dKeKSIIRENS135xOsT3jEs7Ii'}
Response status_code=200
{
"name": "goodday",
  "subject": "user@example.com",
  "activationId": "f81398a389734d018f4c92fbf59e2dbe",
  "publish": false,
  "annotations": [],
  "version": "0.0.1",
  "response": {
     "result": {
       "payload": "good day"
      },
      "success": true,
      "status": "success"
  },
  "end": 1466083636776,
  "logs": [],
  "start": 1466083636724,
  "namespace": "user@example.com"
}
<Response [200]>
>>>
>>>

Test cases and sample code

Simple test cases in the openWhiskLib project on GitHub (tests/openwhisklib.tests.py) demonstrate each function in openWhiskLib.py, showing the inputs and outputs. You can use them to verify that OpenWhisk works with your credentials.

Conclusion

This tutorial has given you a high-level overview of OpenWhisk, as well as samples to upload and run your own code at IBM Bluemix. You've also seen a new Python library to simplify accessing and deploying apps to OpenWhisk. I hope you can make use of openWhiskLib.py. Take it, enhance it, morph it, and make it your own.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Cloud computing, Web development
ArticleID=1038996
ArticleTitle=An easy way to provision and invoke actions in IBM OpenWhisk
publish-date=10252016