Skip to content

Instantly share code, notes, and snippets.

@mjvesa
Created September 25, 2019 19:26
Show Gist options
  • Save mjvesa/3610adb3855c000219f1e3696e264cc8 to your computer and use it in GitHub Desktop.
Save mjvesa/3610adb3855c000219f1e3696e264cc8 to your computer and use it in GitHub Desktop.
Article about writing Vaadin apps in Python

Python and Vaadin 14

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.

Wiggling Python into Vaadin

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.

Entering Python

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.

For the lazy and the curious

The stuff here can be found applied on the Vaadin Skeleton Starter. Check it out at the following address:

https://github.com/mjvesa/vaadin-with-python

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment