Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #599] Add Python documentation #600

Merged
merged 15 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions serverlessworkflow/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
*** Integrations of external services
**** xref:use-cases/advanced-developer-use-cases/integrations/camel-routes-integration.adoc[]
**** xref:use-cases/advanced-developer-use-cases/integrations/custom-functions-knative.adoc[]
**** xref:use-cases/advanced-developer-use-cases/integrations/custom-functions-python.adoc[]
**** xref:use-cases/advanced-developer-use-cases/integrations/expose-metrics-to-prometheus.adoc[]
**** xref:use-cases/advanced-developer-use-cases/integrations/serverless-dashboard-with-runtime-data.adoc[]
*** Testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ The Camel route is responsible to produce the return value in a way that the wor

include::../../pages/_common-content/camel-valid-responses.adoc[]

[[con-func-python]
== Python custom function
{product_name} provides an implementation of a custom function to execute embedded Python scripts and functions. See xref:use-cases/advanced-developer-use-cases/integrations/custom-functions-knative.adoc[Invoking Python from {product_name}]
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[[con-func-knative]]
== Knative custom function

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
= Invoking Python from {product_name}
:compat-mode!:
// Metadata:
:description: Describe Python execution capabilities
:keywords: kogito, workflow, quarkus, serverless, python, AI

This document describes how to integrate python scripts and function into you workflow using {product_name} custom functions. The code appearing in this document is copied from link:{kogito_sw_examples_url}/serverless-workflow-python-quarkus[`serverless-workflow-python-quarkus`] example application and link:{kogito_runtimes_url}/quarkus/addons/python/integration-tests/src/main/resources/PythonService.sw.json[PythonService] integration test.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

== Enable Python support

To enable Python support you need to the python add-on dependency to your {prouct_name} module `pom.xml` file
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,xml]
----
<dependency>
<groupId>org.apache.kie.sonataflow</groupId>
<artifactId>sonataflow-addons-quarkus-python</artifactId>
</dependency>
----

== Invoking embedded Python script.

{product_name} supports of execution python script in the same memory address than the running workflow.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

To invoke a python script the first step is to define a custom python function at the beginning of the flow.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,json]
----
"functions": [
{
"name": "python",
"type": "custom",
"operation": "script:python"
}
]
----

Once done, you can use that function several times to execute arbitrary python code. The python code is provided as argument of the function call through `script` property.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,json]
----
"functionRef":
"name" : "Imports",
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
"refName": "python",
"arguments": {
"script": "import numpy as np"
}
}
----

Previous snippet imports link:https://numpy.org/[numpy] library. The same python function can be invoked again to generate an array containing three random numbers between 0 and 10.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,json]
----
"functionRef": {
"refName": "python",
"arguments": {
"script": "rng = np.random.default_rng().integers(low=0,high=10,size=3)"
}
}
----

To access the result of the embedded python invocation, {product_name} provides an special context variable: `$WORKFLOW.python`. Therefore, if you want to set `rng` variable from previous script as `output` property of the workflow model, you write
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,json]
----
"stateDataFilter" : {
"output" : "{result:$WORKFLOW.python.rng}"
}
----

== Invoking Python function.

You can also invoke functions from standard or custom python modules.

You need to define a serverless workflow function definition that invokes the python function. You should specific, within `operation` property, the name of the python module and function to be invoked when the function is called. You should separate the module name and the function name using `::` and prefix them with `services::python:`
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

The following example defines a function that invokes standard python function link:https://www.geeksforgeeks.org/python-math-factorial-function/[math.factorial(x)]
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
[source,json]
----
"functions" : [ {
"name" : "factorial",
"operation" : "service:python:math::factorial",
"type" : "custom"
}
----

Once you have defined the function, you might call it passing the expected arguments. In the case of factorial, a integer stored in property `x` of the workflow model.

[source,json]
----
"functionRef" : {
"refName": "factorial",
"arguments" : ".x"
}
----

The return value of the function can be handled as any other function result using `actionDataFilter.toStateData` Serverless Workflow construct. The following will set a workflow model property called `result` with the factorial invocation returned value.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,json]
----
"actionDataFilter" : {
"toStateData" : ".result"
}
----

== Further reading

The link:{kogito_sw_examples_url}/serverless-workflow-openvino-quarkus[Openvino] illustrates the powerful AI capabilities of integrating workflows with Python. It is a must seen for all interested on the topic.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

== Additional resources

* xref:core/custom-functions-support.adoc[Custom functions for your {product_name} service]
* xref:core/understanding-jq-expressions.adoc[Understanding JQ expressions]

include::../../../_common-content/report-issue.adoc[]