thomasantony / flybywire

A React-inspired declarative library for building DOM-based user interfaces in pure Python.
MIT License
112 stars 6 forks source link

flybywire is an OS-agnostic, declarative UI library for Python based on Sofi and inspired by Facebook's React framework. The main goal behind this experiment was to build elegant, interactive UIs in pure Python while leveraging web technologies. Eventually, flybywire will use something like Electron rather than a web browser for greater control over what is rendered.

Build Status PyPI version

Overview

The interface is built using a virtual-DOM layer and sent to the browser over WebSockets. All the view logic is written in pure Python. Instead of providing a set of widgets, flybywire allows components to be defined in a declarative manner out of standard HTML tags and CSS using an easy, readable syntax.

As in React, the view is defined as functions of the state. Any changes to the state automatically triggers a redraw of the entire DOM. flybywire uses the virtual-dom library to update only those parts of the DOM that were actually modified.

Example

This is a really simple example to demonstrate the library in action. It shows simple counter whose value can be controlled by two buttons.

from flybywire.ui import Application, Component
from flybywire.dom import h

def CounterView(count):
    """A simple functional stateless component."""
    return h('h1', str(count))

@Application
class CounterApp(Component):
    def __init__(self):
        """Initialize the application."""
        # super(CounterApp, self).__init__()  # Python 2.7
        super().__init__()
        self.set_initial_state(0)

    def render(self):
        """Renders view given application state."""
        return h('div',
                    [CounterView(count=self.state),
                     h('button', '+', onclick = self.increment),
                     h('button', '-', onclick = self.decrement)]
                )

    def increment(self, e):
        """Increments counter."""
        self.set_state(self.state + 1)

    def decrement(self, e):
        """Decrements counter."""
        self.set_state(self.state - 1)

app = CounterApp()
app.start()

flybywire counter demo The example can also be found in examples/counter.py.

Bugs, features and caveats

About the author

Thomas Antony's LinkedIn Profile