Skip to content

Commit

Permalink
Added cloudevent signature type using cloudevents sdk-python (#78)
Browse files Browse the repository at this point in the history
* Version 1.5.0 (#69)

* Revert "Version 2.0.0 (#67)"

This reverts commit f2471b4.

* Revert "Add Cloud Events support for #55 (#56) (#64)"

This reverts commit 8f3fe35.

* Version 1.5.0

* Improve documentation around Dockerfiles (#70)

* Add a link to an example Dockerfile in the top README.md

* Update the inline Dockerfile to match file

* Remove explicit gunicorn installation

* make readme links absolute, useful

Useful for when this readme appears on both github and pypi

* added cloudevents 1.0.0

Signed-off-by: Curtis Mason <[email protected]>

* reverted auto format

Signed-off-by: Curtis Mason <[email protected]>

* lint fixes

Signed-off-by: Curtis Mason <[email protected]>

* changed cloudevents to <=1.0 in setup

Signed-off-by: Curtis Mason <[email protected]>

* made cloudevents==1.0

Signed-off-by: Curtis Mason <[email protected]>

* added cloudevent_view tests

Signed-off-by: Curtis Mason <[email protected]>

* test lint fixes

Signed-off-by: Curtis Mason <[email protected]>

* implemented try_catch in cloudevent view wrapper

Signed-off-by: Curtis Mason <[email protected]>

* import fix

Signed-off-by: Curtis Mason <[email protected]>

* adjusted cloud_run_cloudevents readme

Signed-off-by: Curtis Mason <[email protected]>

* added elif for cloudevent

Signed-off-by: Curtis Mason <[email protected]>

* adjusted README

Signed-off-by: Curtis Mason <[email protected]>

* upgraded to cloudevents 1.0.1

Signed-off-by: Curtis Mason <[email protected]>

* import ordering lint fix

Signed-off-by: Curtis Mason <[email protected]>

* removed event from readme cloudevents section

Signed-off-by: Curtis Mason <[email protected]>

* resolved various nits and reverted event code

Signed-off-by: Curtis Mason <[email protected]>

* dockerfile env variables

Signed-off-by: Curtis Mason <[email protected]>

* Update examples/cloud_run_cloudevents/main.py

Co-authored-by: Dustin Ingram <[email protected]>
Signed-off-by: Curtis Mason <[email protected]>

* cleaned up test_cloudevent_functions

Signed-off-by: Curtis Mason <[email protected]>

* Update examples/cloud_run_cloudevents/Dockerfile

Co-authored-by: Adam Ross <[email protected]>
Signed-off-by: Curtis Mason <[email protected]>

* tunneled cloud_exceptions in flask abort

Signed-off-by: Curtis Mason <[email protected]>

* Added additional documentation in sample code

Signed-off-by: Curtis Mason <[email protected]>

* added time to tests

Signed-off-by: Curtis Mason <[email protected]>

* Update README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update examples/cloud_run_cloudevents/send_cloudevent.py

Co-authored-by: Dustin Ingram <[email protected]>

* Update examples/cloud_run_cloudevents/README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update examples/cloud_run_cloudevents/README.md

Co-authored-by: Dustin Ingram <[email protected]>

* Update src/functions_framework/__init__.py

Co-authored-by: Dustin Ingram <[email protected]>

* Update src/functions_framework/__init__.py

Co-authored-by: Dustin Ingram <[email protected]>

* cloudevents 1.1.0 update

Signed-off-by: Curtis Mason <[email protected]>

* simplified exceptions debug

Signed-off-by: Curtis Mason <[email protected]>

* simplified cloudevent view test

Signed-off-by: Curtis Mason <[email protected]>

* Update src/functions_framework/__init__.py

Co-authored-by: Dustin Ingram <[email protected]>

* shebang cloudevent executable

Signed-off-by: Curtis Mason <[email protected]>

* cloudevents version bump

Signed-off-by: Curtis Mason <[email protected]>

* Removed InvalidStructuredJSON exception

Signed-off-by: Curtis Mason <[email protected]>

* Don't bump version in a feature branch

* Add back missing CHANGELOG lines

* Reformat with latest black

Co-authored-by: Dustin Ingram <[email protected]>
Co-authored-by: Katie McLaughlin <[email protected]>
Co-authored-by: Adam Ross <[email protected]>
  • Loading branch information
4 people authored Oct 22, 2020
1 parent 033de0f commit fccb88c
Show file tree
Hide file tree
Showing 18 changed files with 578 additions and 424 deletions.
19 changes: 6 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,52 +179,45 @@ You can configure the Functions Framework using command-line flags or environmen
| `--host` | `HOST` | The host on which the Functions Framework listens for requests. Default: `0.0.0.0` |
| `--port` | `PORT` | The port on which the Functions Framework listens for requests. Default: `8080` |
| `--target` | `FUNCTION_TARGET` | The name of the exported function to be invoked in response to requests. Default: `function` |
| `--signature-type` | `FUNCTION_SIGNATURE_TYPE` | The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. Default: `http`; accepted values: `http` or `event` or `cloudevent` |
| `--signature-type` | `FUNCTION_SIGNATURE_TYPE` | The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. Default: `http`; accepted values: `http`, `event` or `cloudevent` |
| `--source` | `FUNCTION_SOURCE` | The path to the file containing your function. Default: `main.py` (in the current working directory) |
| `--debug` | `DEBUG` | A flag that allows to run functions-framework to run in debug mode, including live reloading. Default: `False` |


## Enable Google Cloud Functions Events

The Functions Framework can unmarshall incoming
Google Cloud Functions [event](https://cloud.google.com/functions/docs/concepts/events-triggers#events) payloads to `data` and `context` objects.
These will be passed as arguments to your function when it receives a request.
Note that your function must use the `event`-style function signature:


```python
def hello(data, context):
print(data)
print(context)
```

To enable automatic unmarshalling, set the function signature type to `event`
using a command-line flag or an environment variable. By default, the HTTP
using the `--signature-type` command-line flag or the `FUNCTION_SIGNATURE_TYPE` environment variable. By default, the HTTP
signature will be used and automatic event unmarshalling will be disabled.

For more details on this signature type, check out the Google Cloud Functions
For more details on this signature type, see the Google Cloud Functions
documentation on
[background functions](https://cloud.google.com/functions/docs/writing/background#cloud_pubsub_example).

See the [running example](examples/cloud_run_event).

## Enable CloudEvents

The Functions Framework can unmarshall incoming
[CloudEvent](http://cloudevents.io) payloads to a `cloudevent` object.
It will be passed as an argument to your function when it receives a request.
Note that your function must use the `cloudevent`-style function signature

The Functions framework can also unmarshall incoming [CloudEvents](http://cloudevents.io) payloads to the `cloudevent` object. This will be passed as a [cloudevent](https://github.com/cloudevents/sdk-python) to your function when it receives a request. Note that your function must use the `cloudevents`-style function signature:

```python
def hello(cloudevent):
print("Received event with ID: %s" % cloudevent.EventID())
return 200
print(f"Received event with ID: {cloudevent['id']}")
```

To enable automatic unmarshalling, set the function signature type to `cloudevent` using the `--signature-type` command-line flag or the `FUNCTION_SIGNATURE_TYPE` environment variable. By default, the HTTP signature type will be used and automatic event unmarshalling will be disabled.

See the [running example](examples/cloud_run_cloudevents).
For more details on this signature type, check out the Google Cloud Functions documentation on [background functions](https://cloud.google.com/functions/docs/writing/background#cloud_pubsub_example).

## Advanced Examples

Expand Down
4 changes: 2 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Python Functions Frameworks Examples

* [`cloud_run_http`](./cloud_run_http/) - Deploying an HTTP function to [Cloud Run](http://cloud.google.com/run) with the Functions Framework
* [`cloud_run_event`](./cloud_run_event/) - Deploying a [Google Cloud Functions Event](https://cloud.google.com/functions/docs/concepts/events-triggers#events) function to [Cloud Run](http://cloud.google.com/run) with the Functions Framework
* [`cloud_run_cloudevents`](./cloud_run_cloudevents/) - Deploying a [CloudEvent](https://github.com/cloudevents/sdk-python) function to [Cloud Run](http://cloud.google.com/run) with the Functions Framework
* [`cloud_run_event`](./cloud_run_event/) - Deploying a CloudEvent function to [Cloud Run](http://cloud.google.com/run) with the Functions Framework
* [`cloud_run_cloudevents`](./cloud_run_cloudevents/) - Deploying a [CloudEvent](https://github.com/cloudevents/sdk-python) function to [Cloud Run](http://cloud.google.com/run) with the Functions Framework
5 changes: 4 additions & 1 deletion examples/cloud_run_cloudevents/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ FROM python:3.7-slim

# Copy local code to the container image.
ENV APP_HOME /app
ENV PYTHONUNBUFFERED TRUE

WORKDIR $APP_HOME
COPY . .

# Install production dependencies.
RUN pip install gunicorn cloudevents functions-framework
RUN pip install -r requirements.txt
RUN chmod +x send_cloudevent.py

# Run the web service on container startup.
CMD exec functions-framework --target=hello --signature-type=cloudevent
CMD ["functions-framework", "--target=hello", "--signature-type=cloudevent"]
43 changes: 7 additions & 36 deletions examples/cloud_run_cloudevents/README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,23 @@
# Deploying a CloudEvent function to Cloud Run with the Functions Framework
This sample uses the [Cloud Events SDK](https://github.com/cloudevents/sdk-python) to send and receive a CloudEvent on Cloud Run.
# Deploying a CloudEvent Function to Cloud Run with the Functions Framework

This sample uses the [CloudEvents SDK](https://github.com/cloudevents/sdk-python) to send and receive a [CloudEvent](http://cloudevents.io) on Cloud Run.

## How to run this locally

Build the Docker image:

```commandline
docker build --tag ff_example .
docker build -t cloudevent_example .
```

Run the image and bind the correct ports:

```commandline
docker run -p:8080:8080 ff_example
docker run --rm -p 8080:8080 -e PORT=8080 cloudevent_example
```

Send an event to the container:

```python
from cloudevents.sdk import converters
from cloudevents.sdk import marshaller
from cloudevents.sdk.converters import structured
from cloudevents.sdk.event import v1
import requests
import json

def run_structured(event, url):
http_marshaller = marshaller.NewDefaultHTTPMarshaller()
structured_headers, structured_data = http_marshaller.ToRequest(
event, converters.TypeStructured, json.dumps
)
print("structured CloudEvent")
print(structured_data.getvalue())

response = requests.post(url,
headers=structured_headers,
data=structured_data.getvalue())
response.raise_for_status()

event = (
v1.Event()
.SetContentType("application/json")
.SetData('{"name":"john"}')
.SetEventID("my-id")
.SetSource("from-galaxy-far-far-away")
.SetEventTime("tomorrow")
.SetEventType("cloudevent.greet.you")
)

run_structured(event, "http://0.0.0.0:8080/")

docker run -t cloudevent_example send_cloudevent.py
```
6 changes: 3 additions & 3 deletions examples/cloud_run_cloudevents/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# This sample creates a function that accepts a Cloud Event per
# https://github.com/cloudevents/sdk-python
# This sample creates a function using the CloudEvents SDK
# (https://github.com/cloudevents/sdk-python)
import sys


def hello(cloudevent):
print("Received event with ID: %s" % cloudevent.EventID(), file=sys.stdout, flush=True)
print(f"Received event with ID: {cloudevent['id']} and data {cloudevent.data}")
2 changes: 2 additions & 0 deletions examples/cloud_run_cloudevents/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Optionally include additional dependencies here
cloudevents>=1.2.0
requests
36 changes: 36 additions & 0 deletions examples/cloud_run_cloudevents/send_cloudevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/local/bin/python

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from cloudevents.http import CloudEvent, to_structured
import requests
import json


# Create a cloudevent using https://github.com/cloudevents/sdk-python
# Note we only need source and type because the cloudevents constructor by
# default will set "specversion" to the most recent cloudevent version (e.g. 1.0)
# and "id" to a generated uuid.uuid4 string.
attributes = {
"Content-Type": "application/json",
"source": "from-galaxy-far-far-away",
"type": "cloudevent.greet.you"
}
data = {"name":"john"}

event = CloudEvent(attributes, data)

# Send the event to our local docker container listening on port 8080
headers, data = to_structured(event)
requests.post("http://localhost:8080/", headers=headers, data=data)
4 changes: 3 additions & 1 deletion examples/cloud_run_event/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ FROM python:3.7-slim

# Copy local code to the container image.
ENV APP_HOME /app
ENV PYTHONUNBUFFERED TRUE

WORKDIR $APP_HOME
COPY . .

Expand All @@ -12,4 +14,4 @@ RUN pip install gunicorn functions-framework
RUN pip install -r requirements.txt

# Run the web service on container startup.
CMD exec functions-framework --target=hello --signature_type=event
CMD exec functions-framework --target=hello --signature-type=event
3 changes: 0 additions & 3 deletions examples/cloud_run_event/README.md

This file was deleted.

2 changes: 2 additions & 0 deletions examples/cloud_run_http/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ FROM python:3.7-slim

# Copy local code to the container image.
ENV APP_HOME /app
ENV PYTHONUNBUFFERED TRUE

WORKDIR $APP_HOME
COPY . .

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"click>=7.0,<8.0",
"watchdog>=0.10.0",
"gunicorn>=19.2.0,<21.0; platform_system!='Windows'",
"cloudevents<1.0",
"cloudevents>=1.2.0,<2.0.0",
],
entry_points={
"console_scripts": [
Expand Down
Loading

0 comments on commit fccb88c

Please sign in to comment.