Developing Python functions
Python function template structure
When you create a Python function using the kn func
CLI, the project directory looks like a typical Python project, with the exception of an additional func.yaml
configuration file. Both http
and event
trigger functions have the same template structure:
fn
├── func.py (1)
├── func.yaml (2)
├── requirements.txt (3)
└── test_func.py (4)
1 | Python functions have very few restrictions. The only real requirement is that your project contain a func.py file which contains a main() function. |
2 | The func.yaml configuration file is used to determine the image name and registry. |
3 | Additional dependencies can be added to the requirements.txt file as they would be in any other Python project. |
4 | The test_func.py file contains a simple unit test that can be used to test your function locally. |
Dependencies
Developers are not restricted to the dependencies provided in the template requirements.txt
file. Additional dependencies can be added as they would be in any other Python project. When the project is built for deployment, these dependencies will be included in the created runtime container image.
Invoking a function
When using the kn func
CLI to create a function project you can generate a project that responds to CloudEvents, or one that responds to simple HTTP requests. CloudEvents in Knative are transported over HTTP as a POST request, so both function types will listen and respond to incoming HTTP events.
Python functions can be invoked with a simple HTTP request. When an incoming request is received, functions are invoked with a context
object as the first parameter.
Context objects
Functions are invoked by providing a context
object as the first parameter. This object is a Python class with two attributes.
-
The
request
attribute will always be present, and contains the Flaskrequest
object. -
The second attribute,
cloud_event
, will be populated if the incoming request is aCloudEvent
.
Developers may access any CloudEvent
data from the context object.
def main(context: Context):
"""
The context parameter contains the Flask request object and any
CloudEvent received with the request.
"""
print(f"Method: {context.request.method}")
print(f"Event data {context.cloud_event.data})
# ... business logic here
Return values
Functions may return any value supported by Flask because the invocation framework proxies these values directly to the Flask server.
def main(context: Context):
data = { "message": "Howdy!" }
headers = { "content-type": "application/json" }
return body, 200, headers
Functions can set both response codes and headers as secondary and tertiary response values from function invocation.
Returning CloudEvents
Developers can use the @event
decorator to tell the invoker that the function return value must be converted to a CloudEvent
before sending the response.
@event("event_source"="/my/function", "event_type"="my.type")
def main(context):
# business logic here
data = do_something()
# more data processing
return data
This example sends a CloudEvent
as the response value, with a type of "my.type"
, a source of "/my/function"
, and the data property set to data
. The event_source
and event_type
decorator attributes are both optional.
If not specified, the CloudEvent event_source
attribute is set to "/parliament/function"
, and the event_type
attribute is set to "parliament.response"
.
Additional resources
-
See the Flask documentation.
Testing a Python function locally
Python functions can be tested locally on your computer. In the default project that is created when you create a function using kn func create
, there is a test_func.py
file which contains a simple unit test.
-
To run these tests locally, you must install the required dependencies:
$ pip install -r requirements.txt
-
Once you have installed the dependencies, run the tests:
$ python3 test_func.py
The default test framework for Python functions is |