Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar edit for tutorial #76

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 87 additions & 61 deletions PythonFDKIntroduction/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,74 @@
# Introduction to fdk-python

This tutorial introduces the
[Fn Python FDK (Function Development Kit)](https://github.com/fnproject/fdk-python).
If you haven't completed the [Introduction to Fn](../Introduction/README.md)
tutorial you should head over there before you proceed.
This tutorial introduces the [Fn Python FDK (Function Development
Kit)](https://github.com/fnproject/fdk-python). If you haven't completed the
[Introduction to Fn](../Introduction/README.md) tutorial you should head over
there before you proceed.

This tutorial takes you through the Fn developer experience for building
Python functions. It shows how easy it is to build, deploy and test
functions written in Python.

## What is an FDK?

The Fn Project allows developers to choose the intercommunication protocol format between an application and serverless function.
There are currently 3 different formats that Fn defines:

default: whatever an application sends inside the HTTP request body will be transferred to the function
HTTP: the function will receive the full HTTP request
JSON: the function will receive a JSON object very similar to CNCF OpenEvents

What is the difference between these formats? Why are there three and not just one?
The short answer is that the default format is applied to cold functions only,
meaning the functions container lives no longer than the time needed to process a single request.
This means higher latencies due to container start/stop times, etc.
In a high-performance low-latency situation, this may not be acceptable.
In contrast, HTTP and JSON formats are applied to hot functions — meaning that the function stays alive
as long as there are more requests to process, but not longer than the time defined by idle_timeout while waiting for more work).
The HTTP format makes developers feel like they are talking to a web server because it looks very simple.
JSON format is a bit different because Fn automatically performs the steps necessary to assemble a JSON object from the HTTP request.

So, what is an FDK and why do we need it? No matter what kind of format is defined for a particular function,
Fn will serve the requests through STDIN and wait on STDOUT for the response and STDERR for function logs.
In order to make a developer’s life simpler, the Fn team developed a set of libraries for different programming languages like Java, Python, Node, and Go.
The main goal of the FDK is to let developers focus on their functions and hide all routine complexities underneath.

Please note that FDK-Python supports only JSON format.
The Fn Project allows developers to choose the intercommunication protocol
format between an application and a serverless function. There are currently
three different formats that Fn defines:

* default: whatever an application sends inside the HTTP request body will be transferred to the function
* JSON: the function receives a JSON object similar to the [CNCF Cloud Event Format](https://github.com/cloudevents/spec/blob/master/spec.md)
* cloudevent: the function receives a JSON object using the [CNCF Cloud Event Format](https://github.com/cloudevents/spec/blob/master/spec.md).

What is the difference between these
[formats](https://github.com/fnproject/fn/blob/master/docs/developers/function-format.md)?
Why are there three and not just one?

The short answer is the default format is applied only to cold functions.
A cold function container lives no longer than the time needed to process
a single request. This means higher latencies due to container start/stop
times, etc. In a high performance, low latency situation this may not be
acceptable.

In contrast, JSON and CloudEvents formats are applied to hot functions. A hot
function stays alive as long as there are more requests to process, defined by
an `idle_timeout` value. For a developer, the JSON format is a bit different
because Fn automatically assembles a JSON object from the HTTP request. The
CloudEvents format differs in that is explicitly stores JSON data using the
[CNCF CloudEvents
Format](https://github.com/cloudevents/spec/blob/master/spec.md). Effectively,
when JSON data is stored, additional metadata is added.

So what is an FDK and why do we need it? No matter what kind of format is
defined for a particular function, Fn serves the requests through STDIN, waits
on STDOUT for the responses, and sends errors to STDERR for function logging. In
order to make a developer’s life simpler, the Fn team developed a set of
libraries for different programming languages like Java, Python, Node, and Go.
The main goal of an FDK is to let developers focus on their functions and hide
all routine complexity.

**Note:** FDK-Python supports only JSON format.

# Create function's boilerplate

>`mkdir pythonfn`

> `cd pythonfn`

>`fn init --runtime python3.6`
>```sh
> mkdir pythonfn
>
> cd pythonfn
>
> fn init --runtime python3.6
>```

The output will be:
```sh

```yaml
Runtime: python3.6
Function boilerplate generated.
func.yaml created.
```
The Fn CLI created the following files in the directory:

* `func.py`

```python
import fdk
import json
Expand All @@ -72,7 +88,7 @@ if __name__ == "__main__":
```

* `requirements.txt`

```text
fdk
```
Expand All @@ -87,11 +103,12 @@ entrypoint: python3 func.py
format: json
```

Done! Your very simple echo function is ready to be deployed and executed!
Done! A very simple echo function ready to be deployed and executed!

## How to develop with Python's FDK?

Let’s take a look at the echo function:

```python
import fdk
import json
Expand All @@ -110,16 +127,19 @@ if __name__ == "__main__":

```

Getting the FDK is easy because the Fn team is responsible for the FDKs distribution.
With Python 3.6 or greater (no more support for Python 2, hooray!!!) specifically, the Fn team published a consumable wheel distribution which you can find in the Warehouse.
So the bare minimum requirement here is to write a function with exactly the same signature:
```
Getting `fdk-python` is easy because the Fn team is responsible for FDK
distribution. With Python 3.6 or greater (no more support for Python 2,
hooray!!!), the Fn team published a consumable wheel distribution
which you can find in the Warehouse. The minimum requirement here is to
write a function with exactly the same signature:

```python
def handler(context, data=None, loop=None)
```

That’s it! Simple, isn’t it? It takes only a couple of minutes from the idea of the function to its execution. Here are some tips:
That’s it! Simple isn’t it? It takes only a couple of minutes from function idea to execution. Here are some tips:

* handle function can be a coroutine (see Python 3 async/await syntax), this is very useful if you prefer async programming over sync
* Handle function can be a coroutine (see Python 3 async/await syntax), this is very useful if you prefer async programming over sync.

```python
import fdk
Expand All @@ -140,31 +160,36 @@ if __name__ == "__main__":

```

* through the context developers can access request headers, Fn application and route config as well as format-specific attributes request method, etc.
* Through the context developers can access request headers, Fn application and route config as well as format-specific attributes request method, etc.

You can find more information and code samples here and read more about Fn formats [here](https://github.com/fnproject/fn/blob/master/docs/function-format.md).
You can find more information and code samples here and read more about [Fn
formats
here](https://github.com/fnproject/fn/blob/master/docs/function-format.md).

# First run
## First run

To check if you functions runs well Fn CLI offers nifty feature: `fn run`.
It helps you identify whether function's code can be packaged and executed using a wrapper above Docker CLI:
It helps you identify whether a function's code can be packaged and executed using a wrapper around Docker CLI:

>`fn run`
>```sh
> fn run
>```

```bash
```sh
Building image fndemouser/pythonfn:0.0.1 ..........................................
{"message":"Hello World"}
```

This is an initial but still very meaningful step towards setting up a real serverless function with Fn server.
This is a small but still very meaningful step towards setting up a real serverless function with Fn server.

# Deploying your Python Function
## Deploying your Python Function

As we're running the server on the local machine we can save time by not pushing the
generated image out to a remote Docker repository by using the `--local`
option.
Since we're running the server locally, use the `--local` option to save time by
not pushing the generated image out to a remote Docker repository.

>`fn deploy --local --app myapp`
>```sh
> fn deploy --local --app myapp
>```

```sh
Deploying pythonfn to app: myapp at path: /pythonfn
Expand All @@ -176,23 +201,24 @@ Successfully tagged fndemouser/pythonfn:0.0.2
Updating route /pythonfn using image fndemouser/pythonfn:0.0.2...
```

Review the last line of the deploy output. When deployed, a function's
Docker image is associated with a route which is the function's name and
the function's name is taken from the containing directory. In this
case the route is `/pythonfn`.
Review the last line of the output. When deployed, a function's Docker image is
associated with a route which is the function's name. The function's name is
taken from the containing directory, in this case the route is `/pythonfn`.

We can use the route to invoke the function via curl and passing the
You use the route to invoke the function via curl, passing the
JSON input as the body of the call.

> `curl -v http://localhost:8080/r/myapp/pythonfn -d '{"name": "John"}'`
>```sh
> curl -v -H "Content-Type: application/json" -d '{"name": "John"}' http://localhost:8080/r/myapp/pythonfn
>```

```sh
{"message":"Hello John"}
```

Success!

# Wrapping Up
## Wrapping Up

Congratulations! You've just completed an introduction to the Fn Python FDK.
There's so much more in the FDK than we can cover in a brief
Expand Down