In this article we will see how Vaadin UIs can be written using Python. We'll use Jython which implies Python 2.7. GraalVM will be considered in a later article.
First download a server side starter from vaadin.com or any other place. We
won't be using client side templates, but build UIs purely using code. Next
add Jython to the project by adding the maven dependecy to the pom.xml
:
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.1</version>
</dependency>
We'll put our python files to src/main/python
and those should be
included in the classpath. To make that happen, add this to the build
section:
<resources>
<resource>
<directory>src/main/python</directory>
</resource>
</resources>
The prerequisites for including Python code in a Vaadin project are now in place.
We'll access python from Vaadin in a very naive way: create a Python interpreter from the initial route and pass the component into python using a global variable. Then call some method in Python.
There is a one caveat: Vaadin uses reflection to figure out which components are used, and since we are using an interpreter that is opaque to such reflection, the components we use won't be found. A hacky workaround for now is to include the needed components in the initial route. Here is the code required to enter Python:
@Route("")
@PWA(name = "Project Base for Vaadin", shortName = "Project Base")
public class MainView extends VerticalLayout {
public MainView() {
// These are required to have the components available
Button b = new Button();
Notification n = new Notification();
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.set("main_layout", this);
InputStream res = this.getClass().getClassLoader().getResourceAsStream("entrypoint.py");
interpreter.execfile(res);
PyInstance pi = (PyInstance) interpreter.eval("EntryPoint()");
pi.invoke("enter_python");
}
}
Briefly, the MainView
component is placed into the main_layout
variable,
the entrypoint.py
file is loaded, an instance of the EntryPoint
class
is created and finally its enter_python
method is called.
And on the Python side:
from com.vaadin.flow.component.button import Button
from com.vaadin.flow.component.notification import Notification
class EntryPoint:
def __init__(self):
pass
def enter_python(self):
note = Notification("Hello dudes")
button = Button("Click me")
button.addClickListener(lambda event : note.open())
main_layout.add(button)
Here a couple of components are created and the button gets a lambda as a click listener.
The stuff here can be found applied on the Vaadin Skeleton Starter. Check it out at the following address: