Kyma’s serverless Python functions – A short excursion
This is going to be a short blog. I mean: short. My motivation to write it is because I searched for examples and couldn’t find any. So I hope it will help others.
What are Serverless Functions
Kyma and the managed offering SAP BTP Kyma runtime offers so-called serverless functions. These are services you can create within minutes by adding the code and they can be called as web services from the internet (using API rules) or inside the Kyma cluster through kubernetes services.
I think behind the scenes each serverless function is an auto-generated image that is instantiated as a container inside a pod by using a builder job. I prefer to use them when working with events to have modularized blocks of code. They currently come in 2 flavors: Node.js or Python. I think we might see other languages later (Go maybe?). Keep in mind Kyma can run any language, we talk here specifically of serverless functions.
Serverless Function using Python
Open the Kyma UI – click on namespaces and open the namespace you want to use for your test. Click on Workloads → Functions and define a function like that:
Now it’s time to code. And that is simply Python except knowing how to deal with the two objects that are passed into every serverless Python function in Kyma:
Context gives you information about the runtime environment of your functions. What you are mostly interested is the
The data part of the object gives you the payload of the event if the function was called through the event framework (event mesh or NATS). However, you can also call the function simply with an http request. In that case you get the details from the request object in it.
To understand how to address it, it’s helpful to know that the Python web framework being used for the serverless functions is bottle. This is not documented (or I missed it) and so the request is an object of type FormsDict. Therefore if you want to get hold of e.g. the parameters passed to your function it would look like that (here the only parameter is
def main(event, context): requestData = event['extensions']['request'] print("Request parameter URL value: ",requestData.query.url)
and passing data back to the caller would work simply like this:
If you need to use Python libraries you declare them in the dependencies like that:
It’s like the requirements.txt. If you want to log information, just use the print() statement. If you see no output, add the environment variable “PYTHONUNBUFFERED” with the value “1” (not 1).
I should say that you can also work with git repositories instead of the inline editor.
Finally you can extract all your work into a yaml file for deployment to other Kyma instances or just as a backup like that through command line
kubectl -n mynamespace get functions my-serverless-python-function -o=yaml > my-serverless-python-function.yaml
So you have a file you can apply later. I suggest to clean it like removing
status: section and unnecessary fields.
If you add an API rule to you function, you can test it straight away with postman:
When developing and testing, things go wrong. The debugging is limited compared to developing on VSCode. Therefore it’s advisable to add enough
print() statements into your function.
As soon as you save, Kyma will start to build your function and then deploy it in a second step. With a syntax error in your code it will be iterating between build/deploy and won’t leave the orange status.
In such a case click the bottommost “View logs” button on the inline-editor screen (the upper one is for the running pod).
From idea to online function there are minutes – and that is the nice thing. No framework around it needed. You can create a zoo of functions with event-coupling in a few hours. Add an API rule to it and secure it with OAuth2 or JWT and you are set.
For example I needed a function to convert any html page into json to parse the elements in SAP Process Automation. And for that Python just had all what was needed. And I didn’t need to worry about securing it myself as I could build on Kyma. Very handy!