Hello World - Python
We will deploy the app as a Kubernetes Deployment along with a . However, you can also deploy the app as a Knative Serving Service.
Follow the steps below to create the sample code and then deploy the app to your cluster. You can also download a working copy of the sample, by running the following commands:
- A Kubernetes cluster with installed.
- Docker installed and running on your local machine, and a Docker Hub account configured (we’ll use it for a container registry).
Recreating the sample code
Create a new file named and paste the following code. This code creates a basic web server which listens on port 8080:
``` from flask import Flask, request, make_response import uuid
app = Flask(name)
@app.route(‘/‘, methods=[‘POST’]) def hello_world():
app.logger.warning(request.data)
# Respond with another event (optional)
response = make_response({
"msg": "Hi from helloworld-python app!"
})
response.headers["Ce-Id"] = str(uuid.uuid4())
response.headers["Ce-specversion"] = "0.3"
response.headers["Ce-Source"] = "knative/eventing/samples/hello-world"
response.headers["Ce-Type"] = "dev.knative.samples.hifromknative"
return response
if name == ‘main‘:
app.run(debug=True, host='0.0.0.0', port=8080)
```
Add a requirements.txt file containing the following contents:
Flask==1.1.1
In your project directory, create a file named
Dockerfile
and copy the code block below into it. For detailed instructions on dockerizing a Go app, see Deploying Go servers with Docker.FROM python:alpine3.7
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 8080
ENTRYPOINT [ "python" ]
CMD [ "helloworld.py" ]
Create a new file,
sample-app.yaml
and copy the following service definition into the file. Make sure to replace{username}
with your Docker Hub username.# Namespace for sample application with eventing enabled
apiVersion: v1
kind: Namespace
metadata:
name: knative-samples
labels:
knative-eventing-injection: enabled
---
# Helloworld-python app deploment
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-python
namespace: knative-samples
spec:
replicas: 1
selector:
matchLabels: &labels
app: helloworld-python
template:
metadata:
labels: *labels
spec:
containers:
- name: helloworld-python
image: docker.io/{username}/helloworld-python
imagePullPolicy: IfNotPresent
---
# Service that exposes helloworld-python app.
# This will be the subscriber for the Trigger
kind: Service
apiVersion: v1
metadata:
namespace: knative-samples
spec:
selector:
app: helloworld-python
ports:
port: 80
targetPort: 8080
---
# Knative Eventing Trigger to trigger the helloworld-python service
apiVersion: eventing.knative.dev/v1alpha1
kind: Trigger
metadata:
name: helloworld-python
namespace: knative-samples
spec:
broker: default
filter:
attributes:
type: dev.knative.samples.helloworld
source: dev.knative.samples/helloworldsource
subscriber:
ref:
apiVersion: v1
kind: Service
name: helloworld-python
Use Docker to build the sample code into a container. To build and push with Docker Hub, run these commands replacing
{username}
with your Docker Hub username:After the build has completed and the container is pushed to docker hub, you can deploy the sample application into your cluster. Ensure that the container image value in
sample-app.yaml
matches the container you built in the previous step. Apply the configuration usingkubectl
:kubectl apply --filename sample-app.yaml
Above command created a namespace
knative-samples
and labelled it withknative-eventing-injection=enabled
, to enable eventing in the namespace. Verify using the following command:kubectl get ns knative-samples --show-labels
It deployed the helloworld-python app as a K8s Deployment and created a K8s service names helloworld-python. Verify using the following command.
kubectl --namespace knative-samples get deployments helloworld-python
kubectl --namespace knative-samples get svc helloworld-python
It created a Knative Eventing Trigger to route certain events to the helloworld-python application. Make sure that Ready=true
kubectl --namespace knative-samples get trigger helloworld-python
Send and verify CloudEvents
Once you have deployed the application and verified that the namespace, sample application and trigger are ready, let’s send a CloudEvent.
We can send an http request directly to the Broker with correct CloudEvent headers set.
Deploy a curl pod and SSH into it
kubectl --namespace knative-samples run curl --image=radial/busyboxplus:curl -it
Run the following in the SSH terminal
curl -v "default-broker.knative-samples.svc.cluster.local" \
-X POST \
-H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f79" \
-H "Ce-specversion: 0.3" \
-H "Ce-Type: dev.knative.samples.helloworld" \
-H "Ce-Source: dev.knative.samples/helloworldsource" \
-H "Content-Type: application/json" \
-d '{"msg":"Hello World from the curl pod."}'
exit
Verify that event is received by helloworld-python app
Helloworld-python app logs the context and the msg of the above event, and replies back with another event.
-
You should see something similar to:
Event received. Context: Context Attributes,
specversion: 0.3
type: dev.knative.samples.helloworld
source: dev.knative.samples/helloworldsource
id: 536808d3-88be-4077-9d7a-a3f162705f79
time: 2019-10-04T22:35:26.05871736Z
datacontenttype: application/json
Extensions,
knativearrivaltime: 2019-10-04T22:35:26Z
knativehistory: default-kn2-trigger-kn-channel.knative-samples.svc.cluster.local
traceparent: 00-971d4644229653483d38c46e92a959c7-92c66312e4bb39be-00
Hello World Message "Hello World from the curl pod."
Responded with event Validation: valid
Context Attributes,
specversion: 0.2
type: dev.knative.samples.hifromknative
source: knative/eventing/samples/hello-world
id: 37458d77-01f5-411e-a243-a459bbf79682
Data,
{"msg":"Hi from Knative!"}
Play around with the CloudEvent attributes in the curl command and the trigger specification to understand how Triggers work.
helloworld-python
app replies back with an event of type= dev.knative.samples.hifromknative
, and source=knative/eventing/samples/hello-world
. This event enters the eventing mesh via the Broker and can be delivered to other services using a Trigger
Deploy a pod that receives any CloudEvent and logs the event to its output.
kubectl --namespace knative-samples apply --filename - << END
apiVersion: apps/v1
metadata:
name: event-display
namespace: knative-samples
spec:
replicas: 1
selector:
matchLabels: &labels
app: event-display
template:
metadata:
labels: *labels
spec:
containers:
- name: helloworld-python
image: gcr.io/knative-releases/github.com/knative/eventing-sources/cmd/event_display
---
# Service that exposes event-display app.
# This will be the subscriber for the Trigger
kind: Service
apiVersion: v1
metadata:
name: event-display
namespace: knative-samples
spec:
selector:
app: event-display
ports:
- protocol: TCP
port: 80
targetPort: 8080
END
Create a trigger to deliver the event to the above service
kubectl --namespace knative-samples apply --filename - << END
apiVersion: eventing.knative.dev/v1alpha1
kind: Trigger
metadata:
name: event-display
namespace: knative-samples
spec:
broker: default
filter:
attributes:
type: dev.knative.samples.hifromknative
source: knative/eventing/samples/hello-world
subscriber:
ref:
apiVersion: v1
kind: Service
name: event-display
END
Check the logs of event-display service
kubectl --namespace knative-samples logs -l app=event-display --tail=50
You should see something similar to:
cloudevents.Event
Validation: valid
Context Attributes,
specversion: 0.3
type: dev.knative.samples.hifromknative
source: knative/eventing/samples/hello-world
id: 8a7384b9-8bbe-4634-bf0f-ead07e450b2a
time: 2019-10-04T22:53:39.844943931Z
datacontenttype: application/json
Extensions,
knativearrivaltime: 2019-10-04T22:53:39Z
knativehistory: default-kn2-ingress-kn-channel.knative-samples.svc.cluster.local
traceparent: 00-4b01db030b9ea04bb150b77c8fa86509-2740816590a7604f-00
Data,
{
"msg": "Hi from helloworld- app!"
}
Note: You could use the above approach to test your applications too.
Removing the sample app deployment
To remove the sample app from your cluster, delete the service record:
kubectl delete --filename sample-app.yaml