May 30, 2023 4 MIN

Introducing PyWry

PyWry allows you to easily create HTML WebViewers in Python utilizing the WRY library.

blog hero

By utilizing WRY, PyWry uses the built-in browsers specific to each system: WebKit for macOS, WebView2 for Windows, and WebKitGTK for Linux. This clever approach enables PyWry to maintain a remarkably small footprint of approximately 2MB for both Mac and Windows platforms. However, Linux users may need to install a few additional libraries to ensure compatibility.

We're staying true to our Open Source roots by offering this up for everyone to use and contribute too - check the bottom of the article for a link to the repository.

PyWry takes a different approach than other HTML/GUI/Image viewers that exist for Python:

  1. Bokeh, Altair, bqplot, and ipyvolume rely on the Selenium to perform image rendering.
  2. Orca, which uses a headless Electron application that uses the Chromium browser engine built into Electron.
  3. Kaleido, which runs its own build of Chromium as a library.
PyWRY table

✅ - available 🚩 - requires custom code ⛔ - N/A

Beyond serving as an HTML viewer, PyWry offers additional functionalities. Users can take advantage of PyWry's capability to export images, allowing them to save rendered web content as image files. Moreover, PyWry provides the ability to access and manipulate the Document Object Model (DOM), empowering developers to extract and work with structured data from the rendered web page.

GIF 1

Why we made it

PyWry was built partly out of frustration and mostly out of love for Rust and Python. We wanted to create a tool that could be used to display web views from our pure Python program – OpenBB Terminal, but it had to be lightweight and open source.

We tried Tkinter (no JavaScript available), PySide6 (LGPL license and huge footprint), plus many other frameworks but couldn't find exactly what we needed. Enter Tauri and WRY. We had known about Tauri because we were already experimenting with it for another project, but its underlying web view framework, WRY, was the perfect solution. By using PyO3 and Maturin, which allows us to package Rust binaries as Python packages, we were able to harness the power of WRY.

GIF 2

What it does

PyWry has quite a few uses, and I'm sure many more could be added as well.

Currently, in its simplest implementation, PyWry allows sending HTML to a WebView.

import asyncio
import sys

from pywry import PyWry

async def main_loop():

    while True:

        await asyncio.sleep(1)

if __name__ == "__main__":

    try:

        handler = PyWry()
        handler.send_html(
            html="<h1 style='color: red;'>Welcome to PyWry!</h1>",
            title="PyWry Demo",
        )
        handler.start()

        # PyWry creates a new thread for the backend,
        # so we need to run the main loop in the main thread.
        # otherwise, the program will exit immediately.
        handler.loop.run_until_complete(main_loop())
    except KeyboardInterrupt:
        print("Keyboard interrupt detected. Exiting...")
        sys.exit(0)

We also have more advanced examples for sending Plotly Figures and exporting, using Streamlit, and sending an HTML file.

Additionally, here are some other features we are working on:

  • Drop-in replacement for Kaleido – used by Plotly to render figures to an image. In our early testing, we saw a 20-40% speed improvement over Kaleido.
  • Web Scraping – Using this as another way to export the DOM from a WebView.

And of course, we are open to any other features you can dream of. 😊

Examples

Explore the
Terminal Pro


We use cookies

This website uses cookies to meausure and improve your user experience.