## 1. Project Overview & Quickstart (fnproject/fn)

## File: README.md

<a id="top"></a>


**[Quickstart](https://github.com/fnproject/fn#quickstart)&nbsp; | &nbsp;[Tutorials](https://fnproject.io/tutorials)&nbsp; |  &nbsp;[Docs](https://github.com/fnproject/docs)&nbsp; | &nbsp;[API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/fnproject/fn/master/docs/swagger_v2.yml)&nbsp; | &nbsp;[Operating](https://github.com/fnproject/docs/blob/master/fn/README.md#for-operators)&nbsp; | &nbsp;[Flow](https://github.com/fnproject/flow)&nbsp; | &nbsp;[UI](https://github.com/fnproject/ui)**

[](https://circleci.com/gh/fnproject/fn) [](https://godoc.org/github.com/fnproject/fn)
[](https://goreportcard.com/report/github.com/fnproject/fn)

## Welcome
Fn is an event-driven, open source, [Functions-as-a-Service (FaaS)](https://github.com/fnproject/docs/blob/master/fn/general/introduction.md) compute platform that you can run anywhere. Some of its key features:

* Open Source
* Native Docker: use any Docker container as your Function
* Supports all languages
* Run anywhere
  * Public, private and hybrid cloud
  * Import Lambda functions and run them anywhere
* Easy to use for developers
* Easy to manage for operators
* Written in Go
* Simple yet powerful extensibility

The fastest way to experience Fn is to follow the quickstart below, or you can jump right to our [full documentation](https://github.com/fnproject/docs), [API Docs](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/fnproject/fn/master/docs/swagger_v2.yml), or hit us up in our [Slack Community](http://slack.fnproject.io) or [Community Page](https://github.com/fnproject/docs/blob/master/COMMUNITY.md)!


## Quickstart

### Pre-requisites

* Docker 17.10.0-ce or later, Podman 5.7.0 or later installed and running
* [Docker Hub](https://hub.docker.com/) account (or other Docker-compliant registry) (Not required for local development)
* Logged into Registry: ie `docker login` (Not required for local development)

### Install CLI tool

The command line tool isn't required, but it makes things a lot easier. There are a few options to install it:

#### Option 1. Homebrew - macOS

If you're on a Mac and use [Homebrew](https://brew.sh/):

```sh
brew update && brew install fn
```

#### Option 2. Shell script - Linux and macOS

This one works on Linux and macOS (partially on Windows).

If you are running behind a proxy first set your http_proxy and https_proxy environment vars:

```sh
curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
```

This will download a shell script and execute it. If the script asks for a password, that is because it invokes sudo.

#### Option 3. Install the Windows CLI
[Install and run the Fn Client for Windows](https://github.com/fnproject/docs/blob/master/fn/develop/running-fn-client-windows.md).


#### Option 4. Download the bin - Linux, macOS and Windows
Head over to our [releases](https://github.com/fnproject/cli/releases) and download it.

### Before you start

If you are using Podman or Rancher desktop, it is recommended use a volume. The volume will be used by FnServer
to create unix socket file to communicate to other Fn containers.

The volume will be created automatically when you use "--iofs-dir" option in "fn start" and specify the volume name (e.g. fniofsvol).

If you want to create volume manually, you could do:
`docker volume create --opt device=tmpfs --opt type=tmpfs --opt o=size=2M,dev,noexec <volume name>`

The docker command is provided by podman or rancher desktop in this case.

### Run Fn Server

First, start up a Fn server locally:

```sh
fn start
```
or if you are on podman/rancher which you need to use a volume
```sh
fn start --iofs-dir <volume name, or it could be a directory in the host VM for Docker Desktop>
```

iofs-dir allows you to specify a volume (which is required for Podman or Rancher case), or any directory in the
host-vm (for Docker Desktop) if you want to use a specific directory to host the unix socket file. It is usually
not a concern for Docker users.

This will start Fn in single server mode, using an embedded database and message queue. You can find all the
configuration options [here](https://github.com/fnproject/docs/blob/master/fn/operate/options.md). If you are on Windows, check [here](https://github.com/fnproject/docs/blob/master/fn/operate/windows.md).

### SELinux
Most Linux systems have SELinux enabled and FnServer supports running on SELinux.

### Your First Function

Functions are small but powerful blocks of code that generally do one simple thing. Forget about monoliths when using functions, just focus on the task that you want the function to perform. Our CLI tool will help you get started quickly.

Let's create your function. You can use any runtime (ie go, node, java, python, etc.) `hello` will be the name of your function as well as create a directory called `hello`. You can name your function anything.

```sh
fn init --runtime go hello
cd hello
```

We need to create an "app" which acts as a top-level collection of functions and other elements:

```sh
fn create app myapp
```

Deploy your function: 

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

Note: `--local` flag will skip the push to remote container registry making local development faster

Now let's actually run your function using the `invoke` command:

```sh
fn invoke myapp hello
```

That's it! You just deployed and ran your first function! Try updating the function code in `func.go` (or .js, .java, etc.) then deploy it again to see the change.

## Learn More

* Visit [Fn tutorials](http://fnproject.io/tutorials) for step-by-step guides to creating apps with Fn. These tutorials range from introductory to more advanced.
* See our [full documentation](https://github.com/fnproject/docs)
* View our [YouTube Channel](https://www.youtube.com/channel/UCo3fJqEGRx9PW_ODXk3b1nw)
* View our [API Docs](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/fnproject/fn/master/docs/swagger_v2.yml)
* Check out our sub-projects: [Flow](https://github.com/fnproject/flow), [UI](https://github.com/fnproject/ui), [FnLB](https://github.com/fnproject/lb)
* For a full presentation with lots of content you can use in your own presentations, see [The Fn Project Presentation Master](http://deck.fnproject.io)


## Get Help

* [Ask your question on StackOverflow](https://stackoverflow.com/questions/tagged/fn) and tag it with `fn`

## Get Involved

* Join our [Slack Community](http://slack.fnproject.io)
* See our new [Community Page](https://github.com/fnproject/docs/blob/master/community/)
* Learn how to [contribute](https://github.com/fnproject/docs/blob/master/community/CONTRIBUTING.md)
* Find [issues](https://github.com/fnproject/fn/issues) and become a contributor
* Join us at one of our [Fn Events](http://events.fnproject.io) or even speak at one!
* Coming in Q1'19: Regularly scheduled planning meetings for contributing to the Fn Project

## Stay Informed

* [Blog](https://medium.com/fnproject)
* [Twitter](https://twitter.com/fnproject)
* [YouTube](https://www.youtube.com/channel/UCo3fJqEGRx9PW_ODXk3b1nw)
* [Events](http://events.fnproject.io)

---

## File: api/agent/drivers/README.md

This package is intended as a general purpose container abstraction library. With the same code, you can run on Docker, Rkt, etc.

---

## File: api/datastore/sql/migrations/README.md

# Migrations How-To

All migration files should be of the format:

`[0-9]+_[add|remove]_model[_field]*.go`

The number at the beginning of the file name should be monotonically
increasing, from the last highest file number in this directory. E.g. if there
is `11_add_foo_bar.go`, your new file should be `12_add_bar_baz.go`.

Each migration file have to contain both up and down function:

```go
package migrations

import (
	"context"

	"github.com/fnproject/fn/api/datastore/sql/migratex"
	"github.com/jmoiron/sqlx"
)

func up1(ctx context.Context, tx *sqlx.Tx) error {
	_, err := tx.ExecContext(ctx, "ALTER TABLE routes ADD created_at text;")
	return err
}

func down1(ctx context.Context, tx *sqlx.Tx) error {
	_, err := tx.ExecContext(ctx, "ALTER TABLE routes DROP COLUMN created_at;")
	return err
}

func init() {
	Migrations = append(Migrations, &migratex.MigFields{
		VersionFunc: vfunc(1),
		UpFunc:      up1,
		DownFunc:    down1,
	})
}
```

Each migration must initialize a `migratex.Migration` with corresponding
version and up/down function.

We have elected to expose fn's specific sql migrations as an exported global
list `migrations.Migrations` from this package, you must simply add your
migration and append it to this list.

Please note that every database change should be considered as 1 individual
migration (new table, new column, column type change, etc.)

---

## File: clients/README.md

`build.rb` will generate all clients for all Swagger supported languages.

## Building and Deploying Clients

### First Time

If this is your first time building the clients, you'll need to do the following:

```sh
bundle install
```

### Every Time

Everytime the API spec is updated, be sure to bump the version number in `swagger.yml`, then run:

```sh
ruby build.rb
```

Boom. That's it.

## Troubleshooting

Sometimes this will fail due to github caching or something and versions will be off. Just bump version and retry.

---

## File: docs/README.md

##  Project Documentation

### Documentation is located at <https://github.com/fnproject/docs>

---

## File: examples/middleware/README.md

# Middleware Example

This example adds a simple authentication middleware to Fn. See [main.go](main.go) for example code. 

## Building and Running

```sh
go build
./middleware
```

Then test with:

```sh
# First, create an app
fn create app myapp
# And test
curl http://localhost:8080/v1/apps
```

You should get a 401 error. 

Add an auth header and it should go through successfully:

```sh
curl -X GET -H "Authorization: Bearer KlaatuBaradaNikto" http://localhost:8080/v1/apps
```

---

## File: examples/lambda/node/README.md

# Lambda Node Example

This is the exact same function that is in the AWS Lambda tutorial.

Other than a different runtime, this is no different than any other node example.

To use the lambda-nodejs4.3 runtime, use this `fn init` command:

```sh
fn init --runtime lambda-nodejs4.3 --name lambda-node
cat payload.json | fn run
```

---

## File: examples/inputs/README.md

# Tutorial 1: Go Function w/ Input (3 minutes)

Example for using required and optional environment variables defined in the func.yaml file.

Try running the following:

```sh
fn run
# > ERROR: required env var SECRET_1 not found, please set either set it in your environment or pass in `-e SECRET_1=X` flag.
SECRET_1=YOOO fn run
# > info: optional env var SECRET_2 not found.
# > {"SECRET_1":"YOOO","SECRET_2":"","message":"Hello World"}
SECRET_1=YOOO SECRET_2=DAWG fn run
# > {"SECRET_1":"YOOO","SECRET_2":"DAWG","message":"Hello World"}
```

---

## File: examples/grafana/README.md

# Display runtime metrics using Prometheus and Grafana

The Fn server exports metrics using [Prometheus](https://prometheus.io/). This allows [Grafana](https://grafana.com/) to be used to display these metrics graphically. 



## Start an Fn server and deploy some functions

Start an fn server

```sh
fn start
```
Deploy one or more functions as required.
See the [front page](/README.md) or any of the other examples for instructions. 

## Examine the endpoint used to export metrics to Prometheus

The Fn server exports metrics to Prometheus using the API endpoint `/metrics`. 

Try pointing your browser at [http://localhost:8080/metrics](http://localhost:8080/metrics).
This will display the metrics in prometheus format.

## Start Prometheus

Open a terminal window and navigate to the directory containing this example.

Examine the provided Prometheus configuration file:

```
cat prometheus.yml
```

This gives

``` yml
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'fn-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's the Fn server
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'functions'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s

    static_configs:
      # Specify all the Fn servers from which metrics will be scraped
      - targets: ['fnserver:8080'] # Uses /metrics by default
```
Note the last line. This specifies the host and port of the Fn server from which metrics will be obtained. 
If you are running a cluster of Fn servers then you can specify them all here.

Now start Prometheus, specifying this config file.
```
docker run --rm --name=prometheus -d -p 9090:9090 \
  -v `pwd`/prometheus.yml:/etc/prometheus/prometheus.yml \
  --add-host="fnserver:`docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}'`" \
  prom/prometheus
```
Note: This command uses the parameter `--add-host` to define a hostname `fnserver` in the docker container
and configure it to use the IP address on which the Fn server is listening.

Open a browser on Prometheus's graph tool at [http://localhost:9090/graph](http://localhost:9090/graph). If you wish you can use this to view metrics and display metrics from the Fn server: see the [Prometheus](https://prometheus.io/) documentation for instructions. Alternatively continue with the next step to view a ready-made set of graphs in Grafana.

## Start Grafana and load the example dashboard

[Grafana](https://grafana.com/) provides powerful and flexible facilities to create graphs of any metric available to Prometheus. This example provides a ready-made dashboard that displays the numbers of functions that are queued, running, completed and failed. 

Open a terminal window and navigate to the directory containing this example.

Start Grafana on port 3000:
```
docker run --name=grafana -d -p 3000:3000 \
  --add-host="prometheus:`docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}'`" \
  grafana/grafana
```

Open a browser on Grafana at [http://localhost:3000](http://localhost:3000).

Login using the default user `admin` and default password `admin`.

Create a datasource to obtain metrics from Promethesus:
* Click on **Add data source**. In the form that opens:
* Set **Name** to `PromDS` (or whatever name you choose)
* Set **Type** to `Prometheus`
* Set **URL** to `http://prometheus:9090` 
* Set **Access** to `proxy`
* Click **Add** and then **Save and test**

Import the example dashboard that displays metrics from the Fn server:
* Click on the main menu at the top left and choose **Dashboards** and then **Import**
* In the dialog that opens, click **Upload .json file** and specify `fn_grafana_dashboard.json` in this example's directory.
* Specify the Prometheus data source that you just created
* Click **Import**

You should then see the dashboard shown above. Now execute some functions and see the graphs update.

## Tracing metrics

Tracing spans from the Fn server are available as Prometheus metrics. Each span represents a timed internal operation such as a function call, and has
two main attributes: a name that describes the operation being performed (for example `docker_wait_container`), and its duration in seconds. Each span name is represented by a separate histogram metric, which has a name of the form `fn_span__duration_seconds`. 

If the span is associated with a specific function invocation, the corresponding metric is given the labels `fn_app` and `fn_path` which are set to the application name and function path respectively.

A second example dashboard `fn_grafana_dashboard2.json` in this example's directory displays rate and duration data for any number of spans. Use the dropdown lists at the top of the dashboard to choose which tracing spans to examine.

In the following screenshot, the "Choose spans to display rates" dropdown has been used to select `agent_submit` and `serve_http`, and the "Choose spans to display durations" dropdown, has been used to select `agent_cold_exec`, `agent_get_slot`, `agent_submit`, `docker_create_container`, `docker_start_container` and `docker_wait_container`. 



## Docker statistics

During the execution of the docker container, a selected number of statistics from docker are available as Prometheus metrics. The available metrics are listed in the following table:

| Prometheus metric name |
| ------------- |
| `fn_docker_stats_cpu_kernel` |
| `fn_docker_stats_cpu_kernel`  |
| `fn_docker_stats_cpu_user` |
| `fn_docker_stats_disk_read` |
| `fn_docker_stats_disk_write` |
| `fn_docker_stats_mem_limit` |
| `fn_docker_stats_mem_usage` |
| `fn_docker_stats_net_rx` |
| `fn_docker_stats_net_tx` |
 
 Note that if the container runs for a very short length of time there may be insufficient time to obtain statistics before the container terminates.
 
An example dashboard `fn_grafana_dashboard3.json` in this example's directory displays the available docker statistics. Use the dropdown lists at the top of the dashboard to choose which metrics to examine.

---

## File: examples/extensions/README.md

# Extensions Example

This example adds extra endpoints to the API. See [main.go](main.go) for example code.

## Building and Running

```sh
go build
./extensions
```

First create an app `myapp` and a function `myroute`. Then test with:

```sh
curl http://localhost:8080/v1/custom1
curl http://localhost:8080/v1/custom2
curl http://localhost:8080/v1/apps/myapp/custom3
curl http://localhost:8080/v1/apps/myapp/custom4
curl http://localhost:8080/v1/apps/myapp/routes/myroute/custom5
curl http://localhost:8080/v1/apps/myapp/routes/myroute/custom5
```

## 2. Official Technical Reference & Guides (fnproject/docs)

## File: README.md

##  Project Documentation

**[Quickstart](https://github.com/fnproject/fn#quickstart)&nbsp; | &nbsp;[Tutorials](https://fnproject.io/tutorials)&nbsp; |  &nbsp;[Docs](https://github.com/fnproject/docs)&nbsp; | &nbsp;[API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/fnproject/fn/master/docs/swagger_v2.yml)**

Fn is an event-driven, open source, [Functions-as-a-Service (FaaS)](https://github.com/fnproject/docs/blob/master/fn/general/introduction.md) compute platform that you can run anywhere.

## Getting Started
* [Quickstart Tutorial](https://github.com/fnproject/fn#quickstart)
* [Fn Installation](https://fnproject.io/tutorials/install/)
* [Fn Introduction](fn/general/introduction.md)
* Using Fn with Java
    * [Java Tutorial](https://fnproject.io/tutorials/JavaFDKIntroduction/)
    * [Java Examples](fdks/fdk-java)
* Using Fn with Node.js
    * [Node Tutorial](https://fnproject.io/tutorials/node/intro/)
    * [Node Examples](fdks/fdk-node)
* Using Fn with Python
    * [Python Tutorial](https://fnproject.io/tutorials/python/intro/)
    * [Python Examples](fdks/fdk-python)
* Creating Functions with Docker
    * [Create a Function with a Docker Container](https://fnproject.io/tutorials/ContainerAsFunction/)
    * [Create a Function from a Docker image that contains a Node.js app with Oracle DB Support](https://fnproject.io/tutorials/node/custom-db/)
    * [Create a Function with a Linux Command and HotWrap](https://fnproject.io/tutorials/docker/CustomLinuxContainer/)
* [Logging and Debugging Tutorial](https://fnproject.io/tutorials/Troubleshooting/)
    * [Function Debugging](fn/troubleshoot/debug-loglevel.md)
    * [FAQ](fn/general/faq.md)
* Using Fn with Other Languages
    * [Using Fn with C#](https://fnproject.io/tutorials/csharp/intro/)
    * [Using Fn with Go](https://fnproject.io/tutorials/Introduction/)
    * [Using Fn with Ruby](https://fnproject.io/tutorials/ruby/intro/)
* Exploring Fn
    * [Create Apps with Fn](https://fnproject.io/tutorials/Apps/)
    * [Fn Dev with Muliple Contexts](https://fnproject.io/tutorials/basics/UsingContexts/)
    * [Using the Fn RuntimeContext with Functions](https://fnproject.io/tutorials/basics/UsingRuntimeContext/)
* Popular Fn Topics
    * [Fn Function File Format](fn/develop/func-file.md): All the values that can be used in `func.yaml`.
    * [Fn FDKs](fn/develop/fdks.md): Function Development Kits for supported languages.
    * [Fn Runtime Options](fn/operate/options.md)
    * [Kubernetes Helm Chart for Fn](https://github.com/fnproject/fn-helm/)
    * Fn Sub-projects: [Flow](https://github.com/fnproject/flow), [UI](https://github.com/fnproject/ui)
    * [Running Fn in Production](fn/operate/production.md)
    * [Triggers](fn/develop/triggers.md): Using triggers.
    * [Troubleshooting](fn/troubleshoot/README.md): Solutions to common problems when working with Fn.
        * Known Issue: [Trying to invoke a function when using a CentOS based Linux fails with an error message](fn/troubleshoot/known-issues/2019-08-fn-invoke-fails.md)
    * [Using Fn with Podman instead of Docker](fn/develop/podman.md): Use Podman with the Fn client.
    * [Windows: Running Fn Client for Windows](fn/develop/running-fn-client-windows.md): Run the Fn client on Microsoft Windows.


    ## More Fn Docs
    **| [APIs](https://github.com/fnproject/docs/blob/master/fn/develop/README.md#advanced)&nbsp; | 
    [CLI Docs and Reference](https://github.com/fnproject/docs/tree/master/cli)&nbsp; | 
    [Fn Tips for Developers](https://github.com/fnproject/docs/tree/master/fn/develop)&nbsp; | 
    [Fn Tips for Operators](https://github.com/fnproject/docs/blob/master/fn/operate)&nbsp; |**


    ## For Contributors
    We love contributions! To get started, please visit our [community page](community/README.md) and [contributing guidelines](community/CONTRIBUTING.md) page.


    ## Stay Connected to Fn
    **| [StackOverflow](https://stackoverflow.com/questions/tagged/fn)&nbsp; | [Slack Community](http://slack.fnproject.io)&nbsp; | 
    [Blog](https://medium.com/fnproject)&nbsp; | 
    [Twitter](https://twitter.com/fnproject)&nbsp; |
    [YouTube](https://www.youtube.com/channel/UCo3fJqEGRx9PW_ODXk3b1nw)&nbsp; |
    [The Fn Project Presentation Master](http://deck.fnproject.io)&nbsp; |**

---

## File: cli/how-to/README.md

##  CLI How-to

[Manage Fn Servers](manage-server.md)  
[Create and Run Functions](create-run-fn.md)

---

## File: cli/ref/README.md

# Fn Command Reference

[fn build](fn-build.md)  
[fn bump](fn-bump.md)  
[fn config](fn-config.md)  
[fn create](fn-create.md)  
[fn create app](fn-create-app.md)  
[fn create context](fn-create-context.md)  
[fn create function](fn-create-function.md)  
[fn create trigger](fn-create-trigger.md)  
[fn delete](fn-delete.md)  
[fn deploy](fn-deploy.md)  
[fn get](fn-get.md)  
[fn get config](fn-get-config.md)  
[fn help](fn-help.md)  
[fn init](fn-init.md)  
[fn inspect](fn-inspect.md)  
[fn invoke](fn-invoke.md)  
[fn list](fn-list.md)  
[fn list apps](fn-list-apps.md)  
[fn list config](fn-list-config.md)  
[fn list contexts](fn-list-contexts.md)  
[fn list triggers](fn-list-triggers.md)  
[fn migrate](fn-migrate.md)  
[fn push](fn-push.md)  
[fn start](fn-start.md)  
[fn stop](fn-stop.md)  
[fn unset](fn-unset.md)  
[fn update](fn-update.md)  
[fn update app](fn-update-app.md)  
[fn update context](fn-update-context.md)  
[fn update function](fn-update-function.md)  
[fn update server](fn-update-server.md)  
[fn update trigger](fn-update-trigger.md)  
[fn use](fn-use.md)  
[fn version](fn-version.md)  

<sub>version: 0.5.91</sub>

---

## File: cli/README.md

##  CLI Guide


<sub>
**Table of Contents**
[CLI Source Code](#cli-source-code)  
[Fn Command Reference](#fn-command-reference)  
[Fn CLI How-to Guides](#fn-cli-how-to-guides)
</sub>

### CLI Source Code

* [https://github.com/fnproject/cli/](https://github.com/fnproject/cli/)

### Fn Command Reference

[fn build](ref/fn-build.md)  
[fn bump](ref/fn-bump.md)  
[fn config](ref/fn-config.md)  
[fn create](ref/fn-create.md)  
[fn create app](ref/fn-create-app.md)  
[fn create context](ref/fn-create-context.md)  
[fn create function](ref/fn-create-function.md)  
[fn create trigger](ref/fn-create-trigger.md)  
[fn delete](ref/fn-delete.md)  
[fn deploy](ref/fn-deploy.md)  
[fn get](ref/fn-get.md)  
[fn get config](ref/fn-get-config.md)  
[fn help](ref/fn-help.md)  
[fn init](ref/fn-init.md)  
[fn inspect](ref/fn-inspect.md)  
[fn invoke](ref/fn-invoke.md)  
[fn list](ref/fn-list.md)  
[fn list apps](ref/fn-list-apps.md)  
[fn list config](ref/fn-list-config.md)  
[fn list contexts](ref/fn-list-contexts.md)  
[fn list triggers](ref/fn-list-triggers.md)  
[fn migrate](ref/fn-migrate.md)  
[fn push](ref/fn-push.md)  
[fn start](ref/fn-start.md)  
[fn stop](ref/fn-stop.md)  
[fn unset](ref/fn-unset.md)  
[fn update](ref/fn-update.md)  
[fn update app](ref/fn-update-app.md)  
[fn update context](ref/fn-update-context.md)  
[fn update function](ref/fn-update-function.md)  
[fn update server](ref/fn-update-server.md)  
[fn update trigger](ref/fn-update-trigger.md)  
[fn use](ref/fn-use.md)  
[fn version](ref/fn-version.md)  

<sub>version: 0.5.96</sub>


### [Fn CLI How-to Guides](how-to/README.md)

#### Deploy Apps with Fn
* [Manage an Fn Server](how-to/manage-server.md)
* [Create and Run Functions with Fn](how-to/create-run-fn.md)
* [Create an init-image for Fn](how-to/create-init-image.md)

---

## File: community/README.md

#  Project Community

## Welcome!

Before proceeding, please review the Fn [Code of Conduct](CODE_OF_CONDUCT.md).

Welcome to the Fn Project Community! You will find all the resources you need here to join our community, whether as a user, contributor, speaker, partner, or just observer.


## Bi-Weekly Fn Community Call

The Fn Project community calls take place every other Tuesday and are open to anyone. You can find the date of the next call, dial-in information, and past meeting notes here: [http://comcall.fnproject.io](http://comcall.fnproject.io)


## For Contributors

If you are working on the Fn Project, want to work on it or are creating extensions, start with our [contributing guidelines](CONTRIBUTING.md) page.


## Workstreams 

This list is unordered and simply a placeholder to start the conversation. May move to a GitHub Project per issue [1070](https://github.com/fnproject/fn/issues/1070))

1. Fn Server core performance work

2. Terraform scripts for full "prod" deployment on multiple clouds

3. Tighter Kubernetes integration
    - Using CRD's to manage funcs
    - Accessing secrets
    - Using pods to schedule work
    - Possible integrations with Knative build, serve, or eventing

4. Additional triggers
    - Kafka (in progress)
    - OracleDB
    - MySQL
    - Scheduled (CRON like)
    
5. Update and Fix UI (might be complete rewrite)

6. [Fn Flow](https://github.com/fnproject/flow)
    
To start using the Fn Project, visit our main repo here: [https://github.com/fnproject/fn](https://github.com/fnproject/fn)

---

## File: examples/README.md

##  Example
Here are examples that show how to implement and use Fn.

### [FDK-Java Examples](../fdks/fdk-java/README.md)

---

## File: fdks/fdk-ruby/README.md

# Function Development Kit for Ruby 

The Function Development Kit for Ruby (FDK for Ruby) provides a Ruby framework for developing `functions` for us with [Fn](https://fnproject.github.io).

## Function Handler

To use this FDK, you simply need to require this gem.

```ruby
require 'fdk`
```

Then create a function with with the following syntax:

```ruby
def myfunc(context, input)
    # Do some work here
    return output
end
```

* context - provides runtime information for your function, such as configuration values, headers, etc.
* input – This parameter is a string containing body of the request.
* output - is where you can return data back to the caller. Whatever you return will be sent back to the caller.
  * Default output format should be in JSON, as Content-Type header will be `application/json` by default. You can be more flexible if you create and return
    an FDK::Response object instead of a string.

Then simply pass that function to the FDK:

```ruby
FDK.handle(myfunction)
```

## Full Example

```ruby
require 'fdk'

def myfunction(context:, input:)
  input_value = input.respond_to?(:fetch) ? input.fetch('name') : input
  name = input_value.to_s.strip.empty? ? 'World' : input_value
  { message: "Hello #{name}!" }
end

FDK.handle(function: :myfunction)
```

## Running the example that is in the root directory of this repo

```sh
$ echo '{"name":"coolio"}' | fn run
{"message":"Hello coolio!"}
```

You can also specify the format (the default is JSON)

```sh
$ echo '{"name":"coolio"}' | fn run --format json
{"message":"Hello coolio!"}
```

If you want to just pass plain text to the function, specify a format of __default__:

```sh
$ echo 'coolio' | fn run --format default
{"message":"Hello coolio!"}
```

Deploy:

```sh
fn deploy --app myapp --local && echo '{"name":"coolio"}' | fn call myapp /fdk-ruby
```

Change to hot:

Update func.yaml: `format: json`

```sh
fn deploy --app myapp --local && echo '{"name":"coolio"}' | fn call myapp /fdk-ruby
```

## Compare cold and hot

Run

```sh
ruby loop.rb
```

---

## File: fdks/fdk-python/README.md

# FN development kit for Python

Purpose of this library to provide simple interface to parse HTTP 1.1 requests.

Following examples are showing how to use API of this library to work with streaming HTTP requests from Fn service.

## Handling JSON Functions

A main loop is supplied that can repeatedly call a user function with a series of HTTP requests.
In order to utilise this, you can write your `func.py` as follows:

```py
import json
import io

from fdk import response


def handler(ctx, data: io.BytesIO=None):
    name = "World"
    try:
        body = json.loads(data.getvalue())
        name = body.get("name")
    except (Exception, ValueError) as ex:
        print(str(ex))

    return response.Response(
        ctx, response_data=json.dumps(
            {"message": "Hello {0}".format(name)}), 
        headers={"Content-Type": "application/json"}
    )

```

---

## File: fdks/fdk-node/README.md

# Fn Function Development Kit for Node.js

This Function Development Kit makes it easy to deploy Node.js functions to Fn.


## Creating a Node Function

Writing a Node.js function is simply a matter of writing a handler function
that you pass to the FDK to invoke each time your function is called.

Start by creating a node function with `fn init` and installing the FDK:

```sh
fn init --runtime node nodefunc
cd nodefunc
```

This creates a simple hello world function in `func.js`:

```javascript
var fdk = require('@fnproject/fdk');

fdk.handle(function(input) {
  var name = 'World';
  if (input.name) {
    name = input.name;
  }
  response = {'message': 'Hello ' + name}
  return response
})
```

The handler function takes the string input that is sent to the function
and returns a response string.  Using the FDK you don't have to worry about reading
input from standard input and writing to standard output to return your response.
The FDK let's you focus on your function logic and not the mechanics.

Now run it!

```sh
fn run
```

Now you have a basic running Node function that you can modify and add what you want.

From this point on, it's the same as any other function in any language. 
deploy the function:

```sh
fn deploy --app fnfdk --local
```

Once deployed, you and invoke the function:

```sh
echo -n "Tom" | fn call fdkdemo /hello
```

or

```sh
curl -d "Tom" http://localhost:8080/r/fdkdemo/hello
```

In both cases you'll get the response:

```sh
Hello Tom from Node!
```

## Function Context

Function invocation context details are available through an optional function argument.
To receive a context object, simply add a second argument to your handler function.
in the following example the `call_id` is obtained from the context and included in 
the response message:

```javascript
var fdk = require('@fnproject/fdk');

fdk.handle(function(input, ctx) {
  var name = 'World';
  if (input) {
    name = input;
  }
  return 'Hello ' + name + ' from Node call ' + ctx.callId + '!';
})
```

In the case of `default` format functions the context give you access to all environment variables
including those defined through function or app config as well as those automatically provided
by Fn like `app_name`, `path`, `memory`, etc.


## Asynchronous function responses

You return an asynchronous response from a function by returning a Javascript `Promise` from the function body: 

```javascript
var fdk = require('@fnproject/fdk');

fdk.handle(function(input, ctx) {
  return new Promise((resolve, reject) => {
     setTimeout(() => resolve("Hello"), 1000);
  });
})
```

## Handling non-json input and output

By default the FDK will convert input with a content-type matching `application/json` into a JSON object as the function input, if the incoming content type is different from `application/json` then the input will be the raw string value of the input. In both cases,  the raw (string) version of the input is also available in `ctx.body`.

Likewise by default the output of a function will be treated as a JSON object and converted using JSON.stringify - you can change this behaviour by setting the content type of the response in the context using `ctx.responseContentType='application/text-plain'`. Changing the content type to non-json will result in the output being treated as a string.

## Using HTTP headers and setting HTTP status codes

You can read http headers passed into a function invocation using `ctx.protocol.header(key)`, this returns the first header value of the header matching `key` (after canonicalization)  and `ctx.protocol.headers` which returns an object containing all headers.  

```javascript
var fdk = require('@fnproject/fdk');

fdk.handle(function(input, ctx) {
  console.log("Authorization header:" , ctx.protocol.header("Authorization"))
  console.log( ctx.protocol.headers) // prints e.g. { "Content-Type": ["application/json"],"Accept":["application/json","text/plain"] } 
})
```

Outbound headers and the HTTP status code can be modified when the function uses the `json` request format. 

To update the outbound status-code set  `ctx.protocol.statusCode`.  To modify outbound headers use `ctx.protocol.setHeader(k,v)`  or `ctx.protocol.addHeader(k,v)` which set (overwriting existing headers) or add (preserving existing headers) headers to the response respectively.  


```javascript
var fdk = require('@fnproject/fdk');

fdk.handle(function(input, ctx) {
   ctx.protocol.setHeader("Location", "http://example.com")
   ctx.protocol.statusCode = 302
})
```

## Fn and Node.js Dependencies
Fn handles Node.js dependencies in the following way:

* If a `package.json` is present without a `node_modules` directory, an Fn build runs an `npm install` within the build process and installs your dependencies.
* If the `node_modules` is present, Fn assumes you have provided the dependencies yourself and no installation is performed.

---

## File: fdks/fdk-java/examples/string-reverse/README.md

# Example Java Function: String Reverse

This example provides an HTTP trigger endpoint for reversing strings.

```bash
$ curl -d "Hello World" http://localhost:8080/t/string-reverse-app/string-reverse
dlroW olleH
```


## Demonstrated FDK features

This example uses **none** of the Fn FDK for Java features, in fact it doesn't
have any dependency on the FDK for Java.  It is just plain old Java code.

## Step by step

Ensure you have the Fn server running to host your function and provide the HTTP endpoint that invokes it:

(1) Start the server

```sh
$ fn start
```

(2) Create an app for the function

```sh
$ fn create app string-reverse-app
```

(3) Deploy the function to your app from the `string-reverse` directory.

```sh
fn deploy --app string-reverse-app --local
```

(4) Invoke the function and reverse the string.

```sh
echo "Hello World" | fn invoke string-reverse-app string-reverse
dlroW olleH
```

(5) Invoke the function using curl and  a trigger to reverse a string.

```bash
$ curl -d "Hello World" http://localhost:8080/t/string-reverse-app/string-reverse
dlroW olleH
```


## Code walkthrough

The entrypoint to the function is specified in `func.yaml` in the `cmd` key.
It is set to `com.example.fn.StringReverse::reverse`. The whole class
`StringReverse` is shown below:


```java
package com.example.fn;

public class StringReverse {
    public String reverse(String str) {
        return new StringBuilder(str).reverse().toString();
    }
}
```

As you can see, this is plain Java with no references to the Fn API. The
Fn FDK for Java handles the marshalling of the HTTP body into the `str`
parameter as well as the marshalling of the returned reversed string into the HTTP
response body (see [Data Binding](../../DataBinding.md) for more
information on how marshalling is performed).