Last active
November 28, 2022 19:51
-
-
Save parente/bd0b71f15ba0b97139e5 to your computer and use it in GitHub Desktop.
Jupyter Notebooks as OpenWhisk Actions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# Jupyter Notebooks as OpenWhisk Actions\n\n> OpenWhisk on IBM Bluemix: Post your code. We host it. We scale it up. Pay only for what you use.\n\n[OpenWhisk on IBM Bluemix](https://new-console.ng.bluemix.net/openwhisk/) supports Dockerized actions. [Jupyter Kernel Gateway](https://github.com/jupyter/kernel_gateway) can turn annotated Jupyter notebooks into microservices that run in Docker.\n\nLet's put them together and create [Jupyter notebook-powered](https://jupyter.org) Whisk actions! 🎈\n\n<p><a href=\"https://asciinema.org/a/1wkyfecyj2qa4t9gm4bank61y\" target=\"_blank\"><img src=\"https://asciinema.org/a/1wkyfecyj2qa4t9gm4bank61y.png\" width=\"605px\"/></a></p>" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Why?!\n\n1. Build your data analyses in [notebooks](https://jupyter.org).\n2. Deploy them as [OpenWhisk actions](https://new-console.ng.bluemix.net/docs/openwhisk/openwhisk_actions.html).\n3. [Trigger](https://new-console.ng.bluemix.net/docs/openwhisk/openwhisk_triggers_rules.html) them on-demand in your solution.\n4. [Package](https://new-console.ng.bluemix.net/docs/openwhisk/openwhisk_packages.html) them for reuse by others." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Hello World Action\n\nHere's a dirt simple hello world web API. It uses annotations supported by the [Jupyter Kernel Gateway](http://jupyter-kernel-gateway.readthedocs.org/en/latest/http-mode.html#notebook-http-mode) to define the API endpoints. Here it is written in Python. It could be written in [any language supported by Jupyter](https://github.com/ipython/ipython/wiki/IPython-kernels-for-other-languages). " | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "import json", | |
"execution_count": 43, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "def tojson(data):\n '''Shorten the code to respond a little bit.'''\n print(json.dumps(data))", | |
"execution_count": 50, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "REQUEST = json.dumps({\n 'body': {},\n 'headers': {}\n})", | |
"execution_count": 56, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "OpenWhisk requires an `init` endpoint." | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "# POST /init\ntojson({})", | |
"execution_count": 57, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "{}\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "OpenWhisk will `POST` to the `run` endpoint on every action invocation." | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "# POST /run\nreq = json.loads(REQUEST)\nname = req.get('body', {}).get('value', {}).get('name', 'world')\ntojson(data = {\n 'msg': 'Hello {} from a Jupyter Notebook!'.format(name)\n})", | |
"execution_count": 62, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "{\"msg\": \"Hello world from a Jupyter Notebook!\"}\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Deploy It\n\nPublish this notebook to the web somewhere. For simplicity, I've made this one a GitHub gist: https://gist.github.com/parente/bd0b71f15ba0b97139e5.\n\nCreate a Dockerfile:\n\n```\n# Use a barebones image from jupyter/docker-stacks for this\n# simple example. Replace with another docker-stacks image\n# if the notebook has more complex dependencies.\nFROM jupyter/minimal-kernel\n\n# Put the jupyter kernel gateway into microservice mode\nENV KG_API notebook-http\n# Point to our gist as the API definition.\nENV KG_SEED_URI https://gist.githubusercontent.com/parente/bd0b71f15ba0b97139e5/raw/nbwhisk.ipynb\n# Listen on the port OpenWhisk wants.\nENV KG_PORT 8080\nEXPOSE 8080\n```\n\nBuild and push the image:\n\n```\ndocker build --rm -t parente/nbwhisk \ndocker push parente/nbwhisk\n```\n\nCreate the whisk action:\n\n```\nwsk action create --docker nbwhisk parente/nbwhisk\n```\n\nInvoke it:\n\n```\nwsk action invoke --blocking nbwhisk\n```\n\nUpdate the notebook and republish it to the web. Then update the action:\n\n```\nwsk action update --docker nbwhisk parente/nbwhisk\n```\n\nThere's no need to rebuild / repush the Docker image in this example because the notebook lives on the open web. If it resided directly in the Docker image, a rebuild/repush would be in order." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Go Further\n\n* Chain multiple notebooks into aggregate actions.\n* Invoke your actions from other applications using the [OpenWhisk REST API](https://new-console.ng.bluemix.net/apidocs/98#introduction).\n* Combine notebook actions with [other supported service actions](https://new-console.ng.bluemix.net/docs/openwhisk/openwhisk_catalog.html).\n\nMore intriguing demo coming soon ...? 🙈🙉🙊" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "*Copyright (c) IBM Corp. 2016 under the MIT License*" | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3", | |
"language": "python" | |
}, | |
"language_info": { | |
"mimetype": "text/x-python", | |
"nbconvert_exporter": "python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"pygments_lexer": "ipython3", | |
"name": "python", | |
"version": "3.5.1" | |
}, | |
"gist_id": "bd0b71f15ba0b97139e5" | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment