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

    1. 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():

      1. app.logger.warning(request.data)
      2. # Respond with another event (optional)
      3. response = make_response({
      4. "msg": "Hi from helloworld-python app!"
      5. })
      6. response.headers["Ce-Id"] = str(uuid.uuid4())
      7. response.headers["Ce-specversion"] = "0.3"
      8. response.headers["Ce-Source"] = "knative/eventing/samples/hello-world"
      9. response.headers["Ce-Type"] = "dev.knative.samples.hifromknative"
      10. return response

      if name == ‘main‘:

      1. app.run(debug=True, host='0.0.0.0', port=8080)
    1. ```
    1. Add a requirements.txt file containing the following contents:

      1. Flask==1.1.1
    2. 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.

      1. FROM python:alpine3.7
      2. COPY . /app
      3. WORKDIR /app
      4. RUN pip install -r requirements.txt
      5. EXPOSE 8080
      6. ENTRYPOINT [ "python" ]
      7. CMD [ "helloworld.py" ]
    3. 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.

      1. # Namespace for sample application with eventing enabled
      2. apiVersion: v1
      3. kind: Namespace
      4. metadata:
      5. name: knative-samples
      6. labels:
      7. knative-eventing-injection: enabled
      8. ---
      9. # Helloworld-python app deploment
      10. apiVersion: apps/v1
      11. kind: Deployment
      12. metadata:
      13. name: helloworld-python
      14. namespace: knative-samples
      15. spec:
      16. replicas: 1
      17. selector:
      18. matchLabels: &labels
      19. app: helloworld-python
      20. template:
      21. metadata:
      22. labels: *labels
      23. spec:
      24. containers:
      25. - name: helloworld-python
      26. image: docker.io/{username}/helloworld-python
      27. imagePullPolicy: IfNotPresent
      28. ---
      29. # Service that exposes helloworld-python app.
      30. # This will be the subscriber for the Trigger
      31. kind: Service
      32. apiVersion: v1
      33. metadata:
      34. namespace: knative-samples
      35. spec:
      36. selector:
      37. app: helloworld-python
      38. ports:
      39. port: 80
      40. targetPort: 8080
      41. ---
      42. # Knative Eventing Trigger to trigger the helloworld-python service
      43. apiVersion: eventing.knative.dev/v1alpha1
      44. kind: Trigger
      45. metadata:
      46. name: helloworld-python
      47. namespace: knative-samples
      48. spec:
      49. broker: default
      50. filter:
      51. attributes:
      52. type: dev.knative.samples.helloworld
      53. source: dev.knative.samples/helloworldsource
      54. subscriber:
      55. ref:
      56. apiVersion: v1
      57. kind: Service
      58. name: helloworld-python
    1. 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:

    2. 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 using kubectl:

      1. kubectl apply --filename sample-app.yaml
      1. Above command created a namespace knative-samples and labelled it with knative-eventing-injection=enabled, to enable eventing in the namespace. Verify using the following command:

        1. kubectl get ns knative-samples --show-labels
      2. It deployed the helloworld-python app as a K8s Deployment and created a K8s service names helloworld-python. Verify using the following command.

        1. kubectl --namespace knative-samples get deployments helloworld-python
        2. kubectl --namespace knative-samples get svc helloworld-python
      3. It created a Knative Eventing Trigger to route certain events to the helloworld-python application. Make sure that Ready=true

        1. 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.

    1. Deploy a curl pod and SSH into it

      1. kubectl --namespace knative-samples run curl --image=radial/busyboxplus:curl -it
    2. Run the following in the SSH terminal

      1. curl -v "default-broker.knative-samples.svc.cluster.local" \
      2. -X POST \
      3. -H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f79" \
      4. -H "Ce-specversion: 0.3" \
      5. -H "Ce-Type: dev.knative.samples.helloworld" \
      6. -H "Ce-Source: dev.knative.samples/helloworldsource" \
      7. -H "Content-Type: application/json" \
      8. -d '{"msg":"Hello World from the curl pod."}'
      9. 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.

    1. You should see something similar to:

      1. Event received. Context: Context Attributes,
      2. specversion: 0.3
      3. type: dev.knative.samples.helloworld
      4. source: dev.knative.samples/helloworldsource
      5. id: 536808d3-88be-4077-9d7a-a3f162705f79
      6. time: 2019-10-04T22:35:26.05871736Z
      7. datacontenttype: application/json
      8. Extensions,
      9. knativearrivaltime: 2019-10-04T22:35:26Z
      10. knativehistory: default-kn2-trigger-kn-channel.knative-samples.svc.cluster.local
      11. traceparent: 00-971d4644229653483d38c46e92a959c7-92c66312e4bb39be-00
      12. Hello World Message "Hello World from the curl pod."
      13. Responded with event Validation: valid
      14. Context Attributes,
      15. specversion: 0.2
      16. type: dev.knative.samples.hifromknative
      17. source: knative/eventing/samples/hello-world
      18. id: 37458d77-01f5-411e-a243-a459bbf79682
      19. Data,
      20. {"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

    1. Deploy a pod that receives any CloudEvent and logs the event to its output.

      1. kubectl --namespace knative-samples apply --filename - << END
      2. apiVersion: apps/v1
      3. metadata:
      4. name: event-display
      5. namespace: knative-samples
      6. spec:
      7. replicas: 1
      8. selector:
      9. matchLabels: &labels
      10. app: event-display
      11. template:
      12. metadata:
      13. labels: *labels
      14. spec:
      15. containers:
      16. - name: helloworld-python
      17. image: gcr.io/knative-releases/github.com/knative/eventing-sources/cmd/event_display
      18. ---
      19. # Service that exposes event-display app.
      20. # This will be the subscriber for the Trigger
      21. kind: Service
      22. apiVersion: v1
      23. metadata:
      24. name: event-display
      25. namespace: knative-samples
      26. spec:
      27. selector:
      28. app: event-display
      29. ports:
      30. - protocol: TCP
      31. port: 80
      32. targetPort: 8080
      33. END
    2. Create a trigger to deliver the event to the above service

      1. kubectl --namespace knative-samples apply --filename - << END
      2. apiVersion: eventing.knative.dev/v1alpha1
      3. kind: Trigger
      4. metadata:
      5. name: event-display
      6. namespace: knative-samples
      7. spec:
      8. broker: default
      9. filter:
      10. attributes:
      11. type: dev.knative.samples.hifromknative
      12. source: knative/eventing/samples/hello-world
      13. subscriber:
      14. ref:
      15. apiVersion: v1
      16. kind: Service
      17. name: event-display
      18. END
    3. Check the logs of event-display service

      1. kubectl --namespace knative-samples logs -l app=event-display --tail=50

      You should see something similar to:

      1. cloudevents.Event
      2. Validation: valid
      3. Context Attributes,
      4. specversion: 0.3
      5. type: dev.knative.samples.hifromknative
      6. source: knative/eventing/samples/hello-world
      7. id: 8a7384b9-8bbe-4634-bf0f-ead07e450b2a
      8. time: 2019-10-04T22:53:39.844943931Z
      9. datacontenttype: application/json
      10. Extensions,
      11. knativearrivaltime: 2019-10-04T22:53:39Z
      12. knativehistory: default-kn2-ingress-kn-channel.knative-samples.svc.cluster.local
      13. traceparent: 00-4b01db030b9ea04bb150b77c8fa86509-2740816590a7604f-00
      14. Data,
      15. {
      16. "msg": "Hi from helloworld- app!"
      17. }

    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:

    1. kubectl delete --filename sample-app.yaml