Skip to main content

Tests Documentation PyPI pret Binder

PRET

Pret is a library for building full-stack reactive user interfaces in Python, using React as a rendering engine.

Installation

pip install pret pret-joy

To use it with Jupyter, if you install the library in a custom environment (conda, venv, or other), you will likely need to tell Jupyter where to find the front-end files. You can do this by running the following command (only once):

pret update-jupyter-config --apply

Features

  • Python, only Python: pret is written in Python: you can write your both your UI and server actions Python. No need to learn a new language.
  • Client-side rendering: unlike other Python UI frameworks, pret runs primarily in the browser. This enables a fast response time to user actions (like hover events), and a better user experience under degraded network conditions.
  • Built on React: pret uses React as a rendering engine, and benefits from its ecosystem.
  • Reactive: unlike other solutions like ipywidgets, pret is reactive. Only the parts of the UI that need to be updated are re-rendered.
  • State management: in addition to React's local state management (i.e. use_state), pret provides a global and modular state management solution that is synchronized between components, between the browser and the server, and can even be persisted to a file for collaborative editing.
  • Modular: pret is designed to be modular. You can easily create your own components, and reuse them in other pret-based projects.
  • Integrated with Jupyter: pret components can be used in Jupyter notebooks, as well as in standalone web applications.
  • Remote execution: pret can call and use the result of Python functions on the server from the browser

Use it in a notebook

Let's write a simple todo app that should:

  • display a list of todos, that can be checked as done
  • display the number remaining todos
  • change the font to bold as a todo is hovered
  • allow editing the todo list directly in Python

Copy and paste the following code in a notebook:

from pret import component, create_store, run, use_state, use_store_snapshot
from pret_joy import Checkbox, Input, Stack, Typography

store = create_store(
    {
        "faire à manger": True,
        "faire la vaisselle": False,
    },
)


@component
def TodoApp():
    todos = use_store_snapshot(store)
    typed, set_typed = use_state("")
    num_remaining = sum(not ok for ok in todos.values())
    plural = "s" if num_remaining > 1 else ""

    def on_key_down(event):
        if event.key == "Enter":
            store[typed] = False
            set_typed("")

    return Stack(
        *(
            Checkbox(
                label=todo,
                checked=ok,
                on_change=lambda e, t=todo: store.update({t: e.target.checked}),
            )
            for todo, ok in todos.items()
        ),
        Input(
            value=typed,
            on_change=lambda event: set_typed(event.target.value),
            on_key_down=on_key_down,
            placeholder="Add a todo",
        ),
        Typography(
            f"Number of unfinished todo{plural}: {num_remaining}",
            sx={"minWidth": "230px"},  # just to avoid jittering when it's centered
        ),
        spacing=2,
        sx={"m": 1},
    )


TodoApp()

In comparison, the closest alternative using ipywidgets looks like the following snippet:

IPyWidget's implementation
import ipywidgets as widgets

state = {
    "faire à manger": True,
    "faire la vaisselle": False,
}


class IPWTodoApp:
    def __init__(self):
        self.box = widgets.VBox()
        self.render()

    def _repr_mimebundle_(self, *args, **kwargs):
        return self.box._repr_mimebundle_(*args, **kwargs)

    def render(self, *args, **kwargs):
        num_remaining = sum([not checked for _, checked in state.items()])
        plural = "s" if num_remaining > 1 else ""

        def on_input_submit(sender):
            state[input_widget.value] = False
            self.render()

        def create_todo_item(todo, checked):
            def update_todo_status(*args, **kwargs):
                state[todo] = checkbox.value
                self.render()

            checkbox = widgets.Checkbox(
                value=checked,
                description=todo,
                disabled=False,
                indent=False,
            )
            checkbox.observe(update_todo_status, names="value")
            return checkbox

        input_widget = widgets.Text(
            placeholder="Add a todo",
            description="",
            disabled=False,
        )
        input_widget.on_submit(on_input_submit)

        self.box.children = [
            *(create_todo_item(todo, checked) for todo, checked in state.items()),
            input_widget,
            widgets.Label(value=f"Number of unfinished todo{plural}: {num_remaining}"),
        ]


IPWTodoApp()

You also lose some features:

  • the app stops working if the server shuts down
  • hover events cannot be listened to
  • no React dom diffing: the app must either be re-rendered entirely (as in the example), or you must determine specifically which field of which widget to update

Use it in a standalone app

You can also use pret to build standalone web applications. Copy the above code in a file named app.py, and change the last line to

if __name__ == "__main__":
    run(TodoApp)

Then, run the following command, and voilà !

python app.py

Metadata

Release files for pret 0.6.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pret 0.6.4
File Interpreter ABI Platform
pret-0.6.4-py3-none-any.whl Python 3 none any Details

Release files / pret-0.6.4-py3-none-any.whl

Download URL pret-0.6.4-py3-none-any.whl
Size 9.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
67305d8c581657b147c7202c691d1a68baf802a3e7af4327e42ecb18a0fe0535
BLAKE2b-256 checksum
How to use checksums
1c9fc56c726b25346ddefcdb07c8d619259f80c97422e385bb56189c33dbbb42
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.4 This release

1 release file

0.6.3

1 release file

0.6.2

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.2

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page