You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2021/10/05 13:12:07 UTC

[GitHub] [openwhisk-runtime-python] code247 opened a new pull request #117: Updates to readme and packages

code247 opened a new pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117


   This PR addresses following tasks:
   
   - tidy up README to list runtime images and move long tutorial to a separate file.
   - update python package versions.
   - pull common packages to `requirements_common.txt` and reuse it across runtimes.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] dgrove-oss commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
dgrove-oss commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934419706


   yeah, its on my back burner list to go through all of the readme.md files and add /github to the travis url piece like I did here: https://github.com/apache/openwhisk-runtime-docker/commit/4f85c3924663ba871af672d3cfe35efcf31f0e20


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] dgrove-oss commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
dgrove-oss commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934351389


   fwiw, the last travis run on this PR failed because of a missing license header, not a max user problem
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929377430


   The `https://github.com/apache/openwhisk/blob/59b67fe96f44e573f3348afed966a1cdaf80ddf2/tools/actionProxy/invoke.py` is here and its use is straightfoward: `python3 invoke.py init <file>` and `python invoke.py run '<json>'`. It is equivalent to almost all the curl you wrote but simpler to use. 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] dgrove-oss commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
dgrove-oss commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934349914


   We can change the required checks by editing .asf.yaml.  


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah edited a comment on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah edited a comment on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929121152


   Updating the versions of existing packages is OK. Vendors are more cognizant of these updates but we can keep things up to date.
   
   There are some things in the README that should be updated (for example, we remove the "loop" from "actionloop") but since those exist in the current docs, we can fix this subsequent to the refactoring.
   
   Thanks @sciabarracom for the review and thanks @code247 for the contribution 🎉 
   Do you have a CLA on file with Apache, I could not find one.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah closed pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah closed pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom edited a comment on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom edited a comment on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929377430






-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929114153






-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on a change in pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on a change in pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#discussion_r717507709



##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:

Review comment:
       We removed the 2.7 runtime.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] code247 closed pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
code247 closed pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah merged pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah merged pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on a change in pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on a change in pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#discussion_r717503588



##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop

Review comment:
       action loop was renamed to just action.

##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:
+```
+docker build -t actionloop-python-v2.7:1.0-SNAPSHOT $(pwd)/core/python2ActionLoop
+```
+
+2.1. Check docker `IMAGE ID` (3rd column) for repository `actionloop-python-v3.7`
+```
+docker images
+```
+You should see an image that looks something like:
+```
+actionloop-python-v3.7         1.0-SNAPSHOT ...
+```
+
+2.2. Tag image (Optional step). Required if you’re pushing your docker image to a registry e.g. dockerHub
+```
+docker tag <docker_image_ID> <dockerHub_username>/actionloop-python-v3.7:1.0-SNAPSHOT
+```
+
+3. Run docker on localhost with either the following commands:
+```
+docker run -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Or run the container in the background (Add -d (detached) to the command above)
+```
+docker run -d -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Note: If you run your docker container in the background you'll want to stop it with:
+```
+docker stop <container_id>
+```
+Where `<container_id>` is obtained from `docker ps` command bellow
+
+Lists all running containers
+```
+docker ps
+```
+or
+```
+docker ps -a
+```
+You shoulkd see a container named `bloom_whisker` being run
+
+4. Create your function (note that each container can only hold one function)
+In this first example we'll be creating a very simple function
+Create a json file called `python-data-init-run.json` which will contain the function that looks something like the following:
+NOTE: value of code is the actual payload and must match the syntax of the target runtime language, in this case `python`
+```json
+{
+   "value": {
+      "name" : "python-helloworld",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello World!'}"
+   }
+}
+```
+
+To issue the action against the running runtime, we must first make a request against the `init` API
+We need to issue `POST` requests to init our function
+Using curl (the option `-d` signifies we're issuing a POST request)
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget (the option `--post-file` signifies we're issuing a POST request)
+```
+wget --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/init
+```
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly
+
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Now we can invoke/run our function agains the `run` API with:
+Using curl `POST` request
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+curl --data-binary "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget `POST` request. The `-O-` is to redirect `wget` response to `stdout`.
+```
+wget -O- --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+wget -O- --body-file=python-data-init-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly.
+
+You noticed that we’re passing the same file `python-data-init-run.json` from function initialization request to trigger the function. That’s not necessary and not recommended since to trigger a function all we need is to pass the parameters of the function. So in the above example, it's prefered if we create a file called `python-data-params.json` that looks like the following:
+```json
+{
+   "value": {}
+}
+```
+And trigger the function with the following (it also works with wget and postman equivalents):
+```
+curl --data-binary "@python-data-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+
+You can perform the same steps as above using [Postman](https://www.postman.com/) application. Make sure you have the correct request type set and the respective body. Also set the correct headers key value pairs, which for us is "Content-Type: application/json"
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello World!"}
+```
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+## Creating functions with arguments
+
+If your container still running from the previuous example you must stop it and re-run it before proceding. Remember that each python runtime can only hold one function (which cannot be overrided due to security reasons)
+Create a json file called `python-data-init-params.json` which will contain the function to be initialized that looks like the following:
+```json
+{
+   "value": {
+      "name": "python-helloworld-with-params",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello ' + args.get('name') + ' from ' + args.get('place') + '!!!'}"
+   }
+}
+```
+Also create a json file `python-data-run-params.json` which will contain the parameters to the function used to trigger it. Notice here we're creating 2 separate file from the beginning since this is good practice to make the disticntion between what needs to be send via the `init` API and what needs to be sent via the `run` API:
+```json
+{
+   "value": {
+      "name": "UFO",
+      "place": "Mars"
+   }
+}
+```
+
+Now, all we have to do is initialize and trigger our function.
+First, to initialize our function make sure your python runtime container is running if not, spin the container by following step 3.
+Issue a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-data-init-params.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-data-init-params.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Second, to run/trigger the function issue requests against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using curl with  `GET`:
+```
+curl --data-binary "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget with `POST`:
+```
+wget -O- --post-file=python-data-run-params.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using  wget with `GET`:
+```
+wget -O- --body-file=python-data-run-params.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello UFO from Mars!!!"}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+### Advanced function
+
+This function will calculate the nth Fibonacci number. It calculates the nth number of the Fibonacci sequence recursively in `O(n)` time.
+
+```python
+def fibonacci(n, mem):
+   if (n == 0 or n == 1):
+      return 1
+   if (mem[n] == -1):
+      mem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)
+   return mem[n]
+
+def main(args):
+   n = int(args.get('fib_n'))
+   mem = [-1 for i in range(n+1)]
+   result = fibonacci(n, mem)
+   key = 'Fibonacci of n == ' + str(n)
+   return {key: result}
+```
+
+Create a json file called `python-fib-init.json` to initialize our fibonacci function and insert the following. (It’s the same code as above but since we can’t have a string span multiple lines in JSON we need to put all this code in one line and this is how we do it. It’s ugly but not much we can do here)
+```json
+{
+   "value": {
+      "name": "python-recursive-fibonacci",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def fibonacci(n, mem):\n\tif (n == 0 or n == 1):\n\t\treturn 1\n\tif (mem[n] == -1):\n\t\tmem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)\n\treturn mem[n]\n\ndef main(args):\n\tn = int(args.get('fib_n'))\n\tmem = [-1 for i in range(n+1)]\n\tresult = fibonacci(n, mem)\n\tkey = 'Fibonacci of n == ' + str(n)\n\treturn {key: result}"
+   }
+}
+```
+Create a json file called `python-fib-run.json` which will be used to run/trigger our function with the appropriate argument:
+```json
+{
+   "value": {
+      "fib_n": "40"
+   }
+}
+```
+
+Now we’re all set.
+Make sure your python runtime container is running if not, spin the container by following step 3.
+Initialize our fibonacci function by issuing a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-fib-init.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-fib-init.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+You've noticed by now that `init` API always returns `{"ok":true}` for a successful initialized function. And the server, again, will remain silent
+
+Trigger the function by running/triggering the function with a request against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using curl with `GET`:
+```
+curl --data-binary "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using wget with `POST`:
+```
+wget -O- --post-file=python-fib-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Using wget with `GET`:
+```
+wget -O- --body-file=python-fib-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"Fibonacci of n == 40": 165580141}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+#### At this point you can edit python-fib-run.json an try other `fib_n` values. All you have to do is save `python-fib-run.json` and trigger the function again. Notice that here we're just modifying the parameters of our function; therefore, there's no need to re-run/re-initialize our container that contains our Python runtime.

Review comment:
       maybe this could just be a `### Notes` section with two bullets or paragraphs.

##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:
+```
+docker build -t actionloop-python-v2.7:1.0-SNAPSHOT $(pwd)/core/python2ActionLoop
+```
+
+2.1. Check docker `IMAGE ID` (3rd column) for repository `actionloop-python-v3.7`
+```
+docker images
+```
+You should see an image that looks something like:
+```
+actionloop-python-v3.7         1.0-SNAPSHOT ...
+```
+
+2.2. Tag image (Optional step). Required if you’re pushing your docker image to a registry e.g. dockerHub
+```
+docker tag <docker_image_ID> <dockerHub_username>/actionloop-python-v3.7:1.0-SNAPSHOT
+```
+
+3. Run docker on localhost with either the following commands:
+```
+docker run -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Or run the container in the background (Add -d (detached) to the command above)
+```
+docker run -d -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Note: If you run your docker container in the background you'll want to stop it with:
+```
+docker stop <container_id>
+```
+Where `<container_id>` is obtained from `docker ps` command bellow
+
+Lists all running containers
+```
+docker ps
+```
+or
+```
+docker ps -a
+```
+You shoulkd see a container named `bloom_whisker` being run
+
+4. Create your function (note that each container can only hold one function)
+In this first example we'll be creating a very simple function
+Create a json file called `python-data-init-run.json` which will contain the function that looks something like the following:
+NOTE: value of code is the actual payload and must match the syntax of the target runtime language, in this case `python`
+```json
+{
+   "value": {
+      "name" : "python-helloworld",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello World!'}"
+   }
+}
+```
+
+To issue the action against the running runtime, we must first make a request against the `init` API
+We need to issue `POST` requests to init our function
+Using curl (the option `-d` signifies we're issuing a POST request)
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget (the option `--post-file` signifies we're issuing a POST request)
+```
+wget --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/init
+```
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly
+
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Now we can invoke/run our function agains the `run` API with:
+Using curl `POST` request
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+curl --data-binary "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget `POST` request. The `-O-` is to redirect `wget` response to `stdout`.
+```
+wget -O- --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+wget -O- --body-file=python-data-init-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly.
+
+You noticed that we’re passing the same file `python-data-init-run.json` from function initialization request to trigger the function. That’s not necessary and not recommended since to trigger a function all we need is to pass the parameters of the function. So in the above example, it's prefered if we create a file called `python-data-params.json` that looks like the following:
+```json
+{
+   "value": {}
+}
+```
+And trigger the function with the following (it also works with wget and postman equivalents):
+```
+curl --data-binary "@python-data-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+
+You can perform the same steps as above using [Postman](https://www.postman.com/) application. Make sure you have the correct request type set and the respective body. Also set the correct headers key value pairs, which for us is "Content-Type: application/json"
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello World!"}
+```
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+## Creating functions with arguments
+
+If your container still running from the previuous example you must stop it and re-run it before proceding. Remember that each python runtime can only hold one function (which cannot be overrided due to security reasons)
+Create a json file called `python-data-init-params.json` which will contain the function to be initialized that looks like the following:
+```json
+{
+   "value": {
+      "name": "python-helloworld-with-params",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello ' + args.get('name') + ' from ' + args.get('place') + '!!!'}"
+   }
+}
+```
+Also create a json file `python-data-run-params.json` which will contain the parameters to the function used to trigger it. Notice here we're creating 2 separate file from the beginning since this is good practice to make the disticntion between what needs to be send via the `init` API and what needs to be sent via the `run` API:
+```json
+{
+   "value": {
+      "name": "UFO",
+      "place": "Mars"
+   }
+}
+```
+
+Now, all we have to do is initialize and trigger our function.
+First, to initialize our function make sure your python runtime container is running if not, spin the container by following step 3.
+Issue a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-data-init-params.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-data-init-params.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Second, to run/trigger the function issue requests against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using curl with  `GET`:
+```
+curl --data-binary "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget with `POST`:
+```
+wget -O- --post-file=python-data-run-params.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using  wget with `GET`:
+```
+wget -O- --body-file=python-data-run-params.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello UFO from Mars!!!"}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+### Advanced function
+
+This function will calculate the nth Fibonacci number. It calculates the nth number of the Fibonacci sequence recursively in `O(n)` time.
+
+```python
+def fibonacci(n, mem):
+   if (n == 0 or n == 1):
+      return 1
+   if (mem[n] == -1):
+      mem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)
+   return mem[n]
+
+def main(args):
+   n = int(args.get('fib_n'))
+   mem = [-1 for i in range(n+1)]
+   result = fibonacci(n, mem)
+   key = 'Fibonacci of n == ' + str(n)
+   return {key: result}
+```
+
+Create a json file called `python-fib-init.json` to initialize our fibonacci function and insert the following. (It’s the same code as above but since we can’t have a string span multiple lines in JSON we need to put all this code in one line and this is how we do it. It’s ugly but not much we can do here)
+```json
+{
+   "value": {
+      "name": "python-recursive-fibonacci",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def fibonacci(n, mem):\n\tif (n == 0 or n == 1):\n\t\treturn 1\n\tif (mem[n] == -1):\n\t\tmem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)\n\treturn mem[n]\n\ndef main(args):\n\tn = int(args.get('fib_n'))\n\tmem = [-1 for i in range(n+1)]\n\tresult = fibonacci(n, mem)\n\tkey = 'Fibonacci of n == ' + str(n)\n\treturn {key: result}"
+   }
+}
+```
+Create a json file called `python-fib-run.json` which will be used to run/trigger our function with the appropriate argument:
+```json
+{
+   "value": {
+      "fib_n": "40"
+   }
+}
+```
+
+Now we’re all set.
+Make sure your python runtime container is running if not, spin the container by following step 3.
+Initialize our fibonacci function by issuing a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-fib-init.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-fib-init.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+You've noticed by now that `init` API always returns `{"ok":true}` for a successful initialized function. And the server, again, will remain silent
+
+Trigger the function by running/triggering the function with a request against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using curl with `GET`:
+```
+curl --data-binary "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using wget with `POST`:
+```
+wget -O- --post-file=python-fib-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Using wget with `GET`:
+```
+wget -O- --body-file=python-fib-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"Fibonacci of n == 40": 165580141}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+#### At this point you can edit python-fib-run.json an try other `fib_n` values. All you have to do is save `python-fib-run.json` and trigger the function again. Notice that here we're just modifying the parameters of our function; therefore, there's no need to re-run/re-initialize our container that contains our Python runtime.
+
+#### You can also automate most of this process through [docker actions](https://github.com/apache/openwhisk/tree/master/tools/actionProxy) by using `invoke.py`

Review comment:
       It would be helpful to show what `invoke.py` is potentially easier compared to `curl` although it might be nice if we had a Postman collection or something similar to work with an API testing tool.

##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:

Review comment:
       We removed the 2.7 runtime.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah closed pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah closed pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929121152


   Updating the versions of existing packages is OK. Vendors are more cognizant of these updates but we can keep things up to date.
   
   There are some things in the README that should be updated (for example, we remove the "loop" from "actionloop") but since those exist in the current docs, we can fix this subsequent to the refactoring.
   
   Thanks @sciabarracom sciabarra for the review and thanks @code247 for the contribution 🎉 
   Do you have a CLA on file with Apache, I could not find one.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934402943


   Thanks @dgrove-oss - the travis link wasn't showing me the build. Of course, I should've gone to Travis' dashboard directly.
   
   the previous build: https://app.travis-ci.com/github/apache/openwhisk-runtime-python/builds/238685042
   the current build: https://app.travis-ci.com/github/apache/openwhisk-runtime-python/builds/239149380


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929126916


   Not sure what's going on with Travis. @code247 are you rebased to master?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934007244


   @dgrove-oss can we disable the travis check on PRs? There's an issue with Travis reporting max users/seats exhausted. I'm going to try to run the Travis job as a GHA.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929121152






-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] code247 commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
code247 commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929367658


   @rabbah Addressed your comments. I'm not quite sure about `invoke.py`. Just fyi, I haven't added the local build tutorial but rather just moved it from main README given it seemed verbose to be there. Happy to clean it up though! 🙂 
   
   Regarding CI, I have rebased my branch with master but not sure why it is not kicking off.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah edited a comment on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah edited a comment on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929121152


   Updating the versions of existing packages is OK. Vendors are more cognizant of these updates but we can keep things up to date.
   
   There are some things in the README that should be updated (for example, we remove the "loop" from "actionloop") but since those exist in the current docs, we can fix this subsequent to the refactoring.
   
   Thanks @sciabarracom for the review and thanks @code247 for the contribution 🎉 
   Do you have a CLA on file with Apache, I could not find one.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-934491215


   thanks @code247 🎉 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929114153


   I do not think we can update package versions in existing runtimes because this would break compatibility. Usually you do newer versions of libraries in runtimes for newer versions of languages but leave the verions of packages in older runtimes. If you want newer versions of a package for an action you can always use a virtual env. I personally did an update of versions of runtimes and I was told to revert to older version of packages


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] code247 commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
code247 commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-922146906


   @rabbah Can you add yourself / other relevant reviewers? Thank you!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom edited a comment on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom edited a comment on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929377430


   The [`invoke.py` is here](https://github.com/apache/openwhisk/blob/59b67fe96f44e573f3348afed966a1cdaf80ddf2/tools/actionProxy/invoke.py)  and its use is straightfoward: `python3 invoke.py init <file>` and `python invoke.py run '<json>'`. It is equivalent to almost all the curl you wrote but simpler to use. 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] sciabarracom edited a comment on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
sciabarracom edited a comment on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929377430


   The [`invoke.py` is here](https://github.com/apache/openwhisk/blob/59b67fe96f44e573f3348afed966a1cdaf80ddf2/tools/actionProxy/invoke.py)  and its use is straightfoward: `python3 invoke.py init <file>` and `python3 invoke.py run '<json>'`. It is equivalent to almost all the curl you wrote but simpler to use. 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] rabbah commented on a change in pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
rabbah commented on a change in pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#discussion_r717503588



##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop

Review comment:
       action loop was renamed to just action.

##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:
+```
+docker build -t actionloop-python-v2.7:1.0-SNAPSHOT $(pwd)/core/python2ActionLoop
+```
+
+2.1. Check docker `IMAGE ID` (3rd column) for repository `actionloop-python-v3.7`
+```
+docker images
+```
+You should see an image that looks something like:
+```
+actionloop-python-v3.7         1.0-SNAPSHOT ...
+```
+
+2.2. Tag image (Optional step). Required if you’re pushing your docker image to a registry e.g. dockerHub
+```
+docker tag <docker_image_ID> <dockerHub_username>/actionloop-python-v3.7:1.0-SNAPSHOT
+```
+
+3. Run docker on localhost with either the following commands:
+```
+docker run -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Or run the container in the background (Add -d (detached) to the command above)
+```
+docker run -d -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Note: If you run your docker container in the background you'll want to stop it with:
+```
+docker stop <container_id>
+```
+Where `<container_id>` is obtained from `docker ps` command bellow
+
+Lists all running containers
+```
+docker ps
+```
+or
+```
+docker ps -a
+```
+You shoulkd see a container named `bloom_whisker` being run
+
+4. Create your function (note that each container can only hold one function)
+In this first example we'll be creating a very simple function
+Create a json file called `python-data-init-run.json` which will contain the function that looks something like the following:
+NOTE: value of code is the actual payload and must match the syntax of the target runtime language, in this case `python`
+```json
+{
+   "value": {
+      "name" : "python-helloworld",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello World!'}"
+   }
+}
+```
+
+To issue the action against the running runtime, we must first make a request against the `init` API
+We need to issue `POST` requests to init our function
+Using curl (the option `-d` signifies we're issuing a POST request)
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget (the option `--post-file` signifies we're issuing a POST request)
+```
+wget --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/init
+```
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly
+
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Now we can invoke/run our function agains the `run` API with:
+Using curl `POST` request
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+curl --data-binary "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget `POST` request. The `-O-` is to redirect `wget` response to `stdout`.
+```
+wget -O- --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+wget -O- --body-file=python-data-init-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly.
+
+You noticed that we’re passing the same file `python-data-init-run.json` from function initialization request to trigger the function. That’s not necessary and not recommended since to trigger a function all we need is to pass the parameters of the function. So in the above example, it's prefered if we create a file called `python-data-params.json` that looks like the following:
+```json
+{
+   "value": {}
+}
+```
+And trigger the function with the following (it also works with wget and postman equivalents):
+```
+curl --data-binary "@python-data-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+
+You can perform the same steps as above using [Postman](https://www.postman.com/) application. Make sure you have the correct request type set and the respective body. Also set the correct headers key value pairs, which for us is "Content-Type: application/json"
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello World!"}
+```
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+## Creating functions with arguments
+
+If your container still running from the previuous example you must stop it and re-run it before proceding. Remember that each python runtime can only hold one function (which cannot be overrided due to security reasons)
+Create a json file called `python-data-init-params.json` which will contain the function to be initialized that looks like the following:
+```json
+{
+   "value": {
+      "name": "python-helloworld-with-params",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello ' + args.get('name') + ' from ' + args.get('place') + '!!!'}"
+   }
+}
+```
+Also create a json file `python-data-run-params.json` which will contain the parameters to the function used to trigger it. Notice here we're creating 2 separate file from the beginning since this is good practice to make the disticntion between what needs to be send via the `init` API and what needs to be sent via the `run` API:
+```json
+{
+   "value": {
+      "name": "UFO",
+      "place": "Mars"
+   }
+}
+```
+
+Now, all we have to do is initialize and trigger our function.
+First, to initialize our function make sure your python runtime container is running if not, spin the container by following step 3.
+Issue a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-data-init-params.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-data-init-params.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Second, to run/trigger the function issue requests against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using curl with  `GET`:
+```
+curl --data-binary "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget with `POST`:
+```
+wget -O- --post-file=python-data-run-params.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using  wget with `GET`:
+```
+wget -O- --body-file=python-data-run-params.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello UFO from Mars!!!"}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+### Advanced function
+
+This function will calculate the nth Fibonacci number. It calculates the nth number of the Fibonacci sequence recursively in `O(n)` time.
+
+```python
+def fibonacci(n, mem):
+   if (n == 0 or n == 1):
+      return 1
+   if (mem[n] == -1):
+      mem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)
+   return mem[n]
+
+def main(args):
+   n = int(args.get('fib_n'))
+   mem = [-1 for i in range(n+1)]
+   result = fibonacci(n, mem)
+   key = 'Fibonacci of n == ' + str(n)
+   return {key: result}
+```
+
+Create a json file called `python-fib-init.json` to initialize our fibonacci function and insert the following. (It’s the same code as above but since we can’t have a string span multiple lines in JSON we need to put all this code in one line and this is how we do it. It’s ugly but not much we can do here)
+```json
+{
+   "value": {
+      "name": "python-recursive-fibonacci",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def fibonacci(n, mem):\n\tif (n == 0 or n == 1):\n\t\treturn 1\n\tif (mem[n] == -1):\n\t\tmem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)\n\treturn mem[n]\n\ndef main(args):\n\tn = int(args.get('fib_n'))\n\tmem = [-1 for i in range(n+1)]\n\tresult = fibonacci(n, mem)\n\tkey = 'Fibonacci of n == ' + str(n)\n\treturn {key: result}"
+   }
+}
+```
+Create a json file called `python-fib-run.json` which will be used to run/trigger our function with the appropriate argument:
+```json
+{
+   "value": {
+      "fib_n": "40"
+   }
+}
+```
+
+Now we’re all set.
+Make sure your python runtime container is running if not, spin the container by following step 3.
+Initialize our fibonacci function by issuing a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-fib-init.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-fib-init.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+You've noticed by now that `init` API always returns `{"ok":true}` for a successful initialized function. And the server, again, will remain silent
+
+Trigger the function by running/triggering the function with a request against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using curl with `GET`:
+```
+curl --data-binary "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using wget with `POST`:
+```
+wget -O- --post-file=python-fib-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Using wget with `GET`:
+```
+wget -O- --body-file=python-fib-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"Fibonacci of n == 40": 165580141}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+#### At this point you can edit python-fib-run.json an try other `fib_n` values. All you have to do is save `python-fib-run.json` and trigger the function again. Notice that here we're just modifying the parameters of our function; therefore, there's no need to re-run/re-initialize our container that contains our Python runtime.

Review comment:
       maybe this could just be a `### Notes` section with two bullets or paragraphs.

##########
File path: tutorials/local_build.md
##########
@@ -0,0 +1,299 @@
+# Building Python runtime locally
+
+## Pre-requisites
+- [Docker](https://www.docker.com/)
+- [curl](https://curl.se/), [wget](https://www.gnu.org/software/wget/), or [Postman](https://www.postman.com/)
+
+0. Choose/create a folder of your liking
+1. Clone this repo:
+```
+git clone https://github.com/apache/openwhisk-runtime-python
+cd openwhisk-runtime-python
+```
+
+2. Build docker
+
+Build using Python 3.7 (recommended)
+```
+docker build -t actionloop-python-v3.7:1.0-SNAPSHOT $(pwd)/core/python3ActionLoop
+```
+This tutorial assumes you're building with python 3.7. But if you want to use python 2.7 you can use:
+```
+docker build -t actionloop-python-v2.7:1.0-SNAPSHOT $(pwd)/core/python2ActionLoop
+```
+
+2.1. Check docker `IMAGE ID` (3rd column) for repository `actionloop-python-v3.7`
+```
+docker images
+```
+You should see an image that looks something like:
+```
+actionloop-python-v3.7         1.0-SNAPSHOT ...
+```
+
+2.2. Tag image (Optional step). Required if you’re pushing your docker image to a registry e.g. dockerHub
+```
+docker tag <docker_image_ID> <dockerHub_username>/actionloop-python-v3.7:1.0-SNAPSHOT
+```
+
+3. Run docker on localhost with either the following commands:
+```
+docker run -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Or run the container in the background (Add -d (detached) to the command above)
+```
+docker run -d -p 127.0.0.1:80:8080/tcp --name=bloom_whisker --rm -it actionloop-python-v3.7:1.0-SNAPSHOT
+```
+Note: If you run your docker container in the background you'll want to stop it with:
+```
+docker stop <container_id>
+```
+Where `<container_id>` is obtained from `docker ps` command bellow
+
+Lists all running containers
+```
+docker ps
+```
+or
+```
+docker ps -a
+```
+You shoulkd see a container named `bloom_whisker` being run
+
+4. Create your function (note that each container can only hold one function)
+In this first example we'll be creating a very simple function
+Create a json file called `python-data-init-run.json` which will contain the function that looks something like the following:
+NOTE: value of code is the actual payload and must match the syntax of the target runtime language, in this case `python`
+```json
+{
+   "value": {
+      "name" : "python-helloworld",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello World!'}"
+   }
+}
+```
+
+To issue the action against the running runtime, we must first make a request against the `init` API
+We need to issue `POST` requests to init our function
+Using curl (the option `-d` signifies we're issuing a POST request)
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget (the option `--post-file` signifies we're issuing a POST request)
+```
+wget --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/init
+```
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly
+
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Now we can invoke/run our function agains the `run` API with:
+Using curl `POST` request
+```
+curl -d "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+curl --data-binary "@python-data-init-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget `POST` request. The `-O-` is to redirect `wget` response to `stdout`.
+```
+wget -O- --post-file=python-data-init-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using `GET` request
+```
+wget -O- --body-file=python-data-init-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+The above can also be achieved with [Postman](https://www.postman.com/) by setting the headers and body accordingly.
+
+You noticed that we’re passing the same file `python-data-init-run.json` from function initialization request to trigger the function. That’s not necessary and not recommended since to trigger a function all we need is to pass the parameters of the function. So in the above example, it's prefered if we create a file called `python-data-params.json` that looks like the following:
+```json
+{
+   "value": {}
+}
+```
+And trigger the function with the following (it also works with wget and postman equivalents):
+```
+curl --data-binary "@python-data-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+
+You can perform the same steps as above using [Postman](https://www.postman.com/) application. Make sure you have the correct request type set and the respective body. Also set the correct headers key value pairs, which for us is "Content-Type: application/json"
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello World!"}
+```
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+## Creating functions with arguments
+
+If your container still running from the previuous example you must stop it and re-run it before proceding. Remember that each python runtime can only hold one function (which cannot be overrided due to security reasons)
+Create a json file called `python-data-init-params.json` which will contain the function to be initialized that looks like the following:
+```json
+{
+   "value": {
+      "name": "python-helloworld-with-params",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def main(args): return {'payload': 'Hello ' + args.get('name') + ' from ' + args.get('place') + '!!!'}"
+   }
+}
+```
+Also create a json file `python-data-run-params.json` which will contain the parameters to the function used to trigger it. Notice here we're creating 2 separate file from the beginning since this is good practice to make the disticntion between what needs to be send via the `init` API and what needs to be sent via the `run` API:
+```json
+{
+   "value": {
+      "name": "UFO",
+      "place": "Mars"
+   }
+}
+```
+
+Now, all we have to do is initialize and trigger our function.
+First, to initialize our function make sure your python runtime container is running if not, spin the container by following step 3.
+Issue a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-data-init-params.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-data-init-params.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+Server will remain silent in this case
+
+Second, to run/trigger the function issue requests against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or using curl with  `GET`:
+```
+curl --data-binary "@python-data-run-params.json" -H "Content-Type: application/json" http://localhost/run
+```
+Or
+Using wget with `POST`:
+```
+wget -O- --post-file=python-data-run-params.json --header="Content-Type: application/json" http://localhost/run
+```
+Or using  wget with `GET`:
+```
+wget -O- --body-file=python-data-run-params.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"payload": "Hello UFO from Mars!!!"}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+### Advanced function
+
+This function will calculate the nth Fibonacci number. It calculates the nth number of the Fibonacci sequence recursively in `O(n)` time.
+
+```python
+def fibonacci(n, mem):
+   if (n == 0 or n == 1):
+      return 1
+   if (mem[n] == -1):
+      mem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)
+   return mem[n]
+
+def main(args):
+   n = int(args.get('fib_n'))
+   mem = [-1 for i in range(n+1)]
+   result = fibonacci(n, mem)
+   key = 'Fibonacci of n == ' + str(n)
+   return {key: result}
+```
+
+Create a json file called `python-fib-init.json` to initialize our fibonacci function and insert the following. (It’s the same code as above but since we can’t have a string span multiple lines in JSON we need to put all this code in one line and this is how we do it. It’s ugly but not much we can do here)
+```json
+{
+   "value": {
+      "name": "python-recursive-fibonacci",
+      "main" : "main",
+      "binary" : false,
+      "code" : "def fibonacci(n, mem):\n\tif (n == 0 or n == 1):\n\t\treturn 1\n\tif (mem[n] == -1):\n\t\tmem[n] = fibonacci(n-1, mem) + fibonacci(n-2, mem)\n\treturn mem[n]\n\ndef main(args):\n\tn = int(args.get('fib_n'))\n\tmem = [-1 for i in range(n+1)]\n\tresult = fibonacci(n, mem)\n\tkey = 'Fibonacci of n == ' + str(n)\n\treturn {key: result}"
+   }
+}
+```
+Create a json file called `python-fib-run.json` which will be used to run/trigger our function with the appropriate argument:
+```json
+{
+   "value": {
+      "fib_n": "40"
+   }
+}
+```
+
+Now we’re all set.
+Make sure your python runtime container is running if not, spin the container by following step 3.
+Initialize our fibonacci function by issuing a `POST` request against the `init` API with the following command:
+Using curl:
+```
+curl -d "@python-fib-init.json" -H "Content-Type: application/json" http://localhost/init
+```
+Using wget:
+```
+wget --post-file=python-fib-init.json --header="Content-Type: application/json" http://localhost/init
+```
+Client expected response:
+```
+{"ok":true}
+```
+You've noticed by now that `init` API always returns `{"ok":true}` for a successful initialized function. And the server, again, will remain silent
+
+Trigger the function by running/triggering the function with a request against the `run` API with the following command:
+Using curl with `POST`:
+```
+curl -d "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using curl with `GET`:
+```
+curl --data-binary "@python-fib-run.json" -H "Content-Type: application/json" http://localhost/run
+```
+Using wget with `POST`:
+```
+wget -O- --post-file=python-fib-run.json --header="Content-Type: application/json" http://localhost/run
+```
+Using wget with `GET`:
+```
+wget -O- --body-file=python-fib-run.json --method=GET --header="Content-Type: application/json" http://localhost/run
+```
+
+After you trigger the function with one of the above commands you should expect the following client response:
+```
+{"Fibonacci of n == 40": 165580141}
+```
+
+And Server expected response:
+```
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+```
+
+#### At this point you can edit python-fib-run.json an try other `fib_n` values. All you have to do is save `python-fib-run.json` and trigger the function again. Notice that here we're just modifying the parameters of our function; therefore, there's no need to re-run/re-initialize our container that contains our Python runtime.
+
+#### You can also automate most of this process through [docker actions](https://github.com/apache/openwhisk/tree/master/tools/actionProxy) by using `invoke.py`

Review comment:
       It would be helpful to show what `invoke.py` is potentially easier compared to `curl` although it might be nice if we had a Postman collection or something similar to work with an API testing tool.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [openwhisk-runtime-python] code247 commented on pull request #117: Updates to readme and packages

Posted by GitBox <gi...@apache.org>.
code247 commented on pull request #117:
URL: https://github.com/apache/openwhisk-runtime-python/pull/117#issuecomment-929367658


   @rabbah Addressed your comments. I'm not quite sure about `invoke.py`. Just fyi, I haven't added the local build tutorial but rather just moved it from main README given it seemed verbose to be there. Happy to clean it up though! 🙂 
   
   Regarding CI, I have rebased my branch with master but not sure why it is not kicking off.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@openwhisk.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org