PyWry is a cross-platform rendering engine and GUI toolkit for Python. One API, three output targets:
- Native window — OS webview via PyTauri. Not Qt, not Electron.
- Jupyter widget — anywidget or FastAPI + WebSocket, works in JupyterLab and notebook environments.
- Browser tab — FastAPI server with Redis state backend for horizontal scaling and RBAC.
Python 3.10–3.14, virtual environment recommended.
pip install pywry| Extra | When to use |
|---|---|
pip install 'pywry[notebook]' |
Jupyter / anywidget integration |
pip install 'pywry[mcp]' |
MCP server for AI agents |
pip install 'pywry[freeze]' |
PyInstaller hook for standalone executables |
pip install 'pywry[all]' |
Everything above |
Linux only — install system webview dependencies first:
sudo apt-get install libwebkit2gtk-4.1-dev libgtk-3-dev libglib2.0-dev \
libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \
libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 \
libxcb-shape0 libgl1 libegl1from pywry import PyWry
app = PyWry()
app.show("Hello World!")
app.block()from pywry import PyWry, Toolbar, Button
app = PyWry()
def on_click(data, event_type, label):
app.emit("pywry:set-content", {"selector": "h1", "text": "Clicked!"}, label)
app.show(
"<h1>Hello</h1>",
toolbars=[Toolbar(position="top", items=[Button(label="Click me", event="app:click")])],
callbacks={"app:click": on_click},
)
app.block()from pywry import PyWry
import pandas as pd
app = PyWry()
df = pd.DataFrame({"name": ["Alice", "Bob", "Carol"], "age": [30, 25, 35]})
def on_select(data, event_type, label):
names = ", ".join(row["name"] for row in data["rows"])
app.emit("pywry:alert", {"message": f"Selected: {names}"}, label)
app.show_dataframe(df, callbacks={"grid:row-selected": on_select})
app.block()from pywry import PyWry
import plotly.express as px
app = PyWry(theme="light")
fig = px.scatter(px.data.iris(), x="sepal_width", y="sepal_length", color="species")
app.show_plotly(fig)
app.block()- 18 toolbar components —
Button,Select,MultiSelect,TextInput,SecretInput,SliderInput,RangeInput,Toggle,Checkbox,RadioGroup,TabGroup,Marquee,Modal, and more. All Pydantic models, 7 layout positions. - Two-way events —
app.emit()andapp.on()bridge Python and JavaScript in both directions. Pre-wired Plotly and AgGrid events included. - Theming — light/dark modes, 60+ CSS variables, hot reload during development.
- Security — token auth, CSP headers,
SecuritySettings.strict()/.permissive()/.localhost()presets.SecretInputstores values server-side, never in HTML. - Standalone executables — PyInstaller hook ships with
pywry[freeze]. No.specedits or--hidden-importflags required. - MCP server — 25 tools, 8 skills, 20+ resources for AI agent integration.
pip install 'pywry[mcp]'
pywry mcp --transport stdioSee the MCP docs for Claude Desktop setup and tool reference.
pip install 'pywry[freeze]'
pyinstaller --windowed --name MyApp my_app.pyThe output in dist/MyApp/ is fully self-contained. Target machines need no Python installation — only the OS webview (WebView2 on Windows 10 1803+, WKWebView on macOS, libwebkit2gtk on Linux).
- Getting Started — installation, quick start, rendering paths
- Concepts — events, configuration, state, hot reload, RBAC
- Components — live previews for all toolbar components
- API Reference — auto-generated docs for every class and function
- MCP Server — AI agent integration
Apache 2.0 — see LICENSE.
