Skip to main content

tkwry

License: MIT PyPI - Python Version GitHub Release PyPI Version Downloads Status: Alpha CI

Keep Tkinter — give it the WebView it never had.

Embed a real system WebView (wry) inside your Frame: modern HTML, JS, and IPC in the same layout as your buttons and tabs — one mainloop, no floating overlay.

Alpha — Early preview (see PyPI badge for the current version). APIs and behavior may change without notice. Not recommended for production use yet.


📖 Overview

Tkinter is still a solid GUI shell — it just had no first-class way to host modern web content inside a widget. Overlay-style WebViews drift out of sync when you move, resize, or switch tabs.

tkwry fills that missing piece:

  • True child embedding — build_as_child via HWND, NSView, or X11 window ID
  • One event loop — Tk mainloop only; no separate app runtime
  • Local apps — app= serves HTML/CSS/JS via tkwry:// (no localhost HTTP server)
  • IPC / RPC / emit — JS↔Python events, request/response, and streams without freezing the UI
  • Trust boundaries — IPC/RPC default to the initial origin; untrusted=True for arbitrary sites
  • Layout-aware — tracks pack / grid / place, tabs, and PanedWindow

Pre-built abi3 wheels ship for Windows and macOS. Linux is source-only (best-effort by design) — see Platform notes.


🗂 Documentation

Topic Doc
Usage (minimal app, app=, hidden hosts, UA, API) docs/usage.md
Trust boundaries (untrusted, bridge_origins, recipes) docs/trust.md
IPC / RPC / emit (expose, call / stream, cancel, limits) docs/rpc.md
Platform notes (Windows / macOS / Linux, print, window chrome) docs/platforms.md
Packaging (PyInstaller / Nuitka notes — not CI-verified in 0.1.x) docs/packaging.md

🔧 Requirements

  • Python 3.10+
  • Tkinter (included with most Python builds)
  • Building from source (git clone, pip install git+…, or Linux) — Rust toolchain (stable); pip uses maturin as the build backend
  • Windows (x86_64, arm64) — WebView2 Runtime (no fallback engine; see Platform notes)
  • macOS — 11 (Big Sur)+, arm64 or x86_64; system WKWebView
  • Linux — WebKitGTK 4.1 + GTK 3; X11 or XWayland ($DISPLAY); source build only (see Installation and Platform notes)

📦 Installation

PyPI (recommended — Windows / macOS wheels)

pip install tkwry

From a git clone (source build)

Cloning the repo and installing locally compiles the Rust extension on your machine. You need a Rust toolchain (rustup) and platform runtimes from Requirements above (WebView2 on Windows, etc.). pip pulls in maturin automatically as the build backend.

git clone https://github.com/mashu3/tkwry.git
cd tkwry
pip install -e .

Use this for development and for running the examples from the tree.

Install a git revision with pip (source build)

pip install git+https://github.com/mashu3/tkwry.git

This builds from source (sdist via git), not a pre-built wheel — needs Rust, same as pip install .. Prefer the PyPI wheel on Windows and macOS unless you need unreleased commits.

Linux (source install)

Install system dependencies, then build from source (support posture: Platform notes):

# Debian / Ubuntu
sudo apt install \
  libwebkit2gtk-4.1-dev \
  libgtk-3-dev \
  libglib2.0-dev

# Runtime (for end users of your app)
# sudo apt install libwebkit2gtk-4.1-0 libgtk-3-0

pip install maturin
git clone https://github.com/mashu3/tkwry.git
cd tkwry
pip install .

GTK events are pumped automatically on a Tk timer while your app runs.


🚀 Usage

Basic WebView

import tkinter as tk
from tkwry import WebView

root = tk.Tk()
root.geometry("900x600")

frame = tk.Frame(root, bg="#222")
frame.pack(fill="both", expand=True, padx=8, pady=8)

web = WebView(frame, url="https://github.com")
web.when_failed(lambda exc: print("native create failed:", exc))

root.mainloop()

The constructor does not raise if native create fails. Handle when_failed / <<WebViewCreateFailed>>. Minimal app, app=, hidden hosts, User-Agent, downloads, cleanup, and the API table: Usage (Minimal app). IPC / RPC / stream: docs/rpc.md. Trust (untrusted, bridge_origins): docs/trust.md.


⚠️ Known limitations

Short checklist — details live in Platform notes (especially macOS embedding).

  • Alpha — APIs may change; not for production yet (see banner above)
  • Windows — WebView2 Runtime required; missing runtime → creation_failed / <<WebViewCreateFailed>> (gated APIs raise WebViewCreationError with install text)
  • Print — web.print() opens the system dialog; no print_to_pdf, no return value, no success/fail/cancel (wry has none). macOS: print_with_options(…margins…) (still no result); Win/Linux → OSError. See Platform notes — Print
  • Downloads — cancel is start-deny only (on_download → False / allowlist); no mid-flight abort, pause/resume, or progress % until wry exposes them. in_flight_downloads is observational. See Platform notes — Downloads
  • Window chrome — title / icon / geometry / fullscreen / min/max / -topmost are the host Toplevel (configure_window); WebView size follows the Frame (sync_bounds). See Usage — Layout / resize
  • Windows DevTools — wry/WebView2 reports is_devtools_open() as False and close_devtools() is a no-op; open_devtools() still opens the inspector
  • Linux — no PyPI wheel (by design); best-effort source install
  • Linux concurrent eval_js_with_callback — evaluating on multiple WebViews at once can stall WebKitGTK; prefer sequential evals (see Linux)
  • Shared WebSession + app= — WebViews that share a non-ephemeral session must use the same app= root (ValueError otherwise; Linux can register tkwry:// only once per context); do not share a persistent profile with untrusted sites
  • Trust / external content — RPC/IPC default to the initial origin (optional path prefix / bridge_allow); bridge_origins="*" warns and needs expose(..., allow_any_origin=True); app= locks navigation to tkwry:// (navigation_allow / open_external=True for extra origins + system browser); untrusted=True also denies downloads unless download_allow / on_download permits (see Trust boundaries)
  • macOS DevTools — create with devtools=True, then open_devtools() (flag alone does not open; open_devtools() without the flag is a no-op on macOS); uses private APIs — avoid in Mac App Store builds
  • macOS IME / focus — not Safari-parity; mid-composition focus flips can mis-route input
  • macOS import order — import tkwry before AppKit/NSApplication, or you may see a double titlebar
  • url() on macOS — may be None for inline HTML until a concrete load_url (WKWebView has no document NSURL)
  • Sync hooks / queues — on_navigation / on_new_window / create-time permission_handler may block WebKit up to ~60s; do not create a WebView from on_new_window (use open_external=True / open_in_browser); async event queues cap at 2048; IPC/RPC messages cap at 10 MiB (see Usage — Navigation / lifecycle callbacks)
  • RPC cancel / destroy — timeout, JS cancel, and destroy() are cooperative only (rpc_cancelled()), including open streams; Python cannot preempt a running worker. destroy() joins the pool for ~2 seconds; leftover threads are logged to stderr (see IPC / RPC / emit)
  • Eval / navigation timeout — eval_js_with_callback timeout (30s) is WebViewTimeoutError (on_error, <<WebViewEvalFailed>>, last_eval_error); on_navigation / on_new_window timeout still returns the default deny and signals WebViewNavigationError (<<WebViewNavigationFailed>>, last_navigation_error) — not raised on the WebKit thread
  • Drag & drop — WebView area only (use tkinterdnd2 for arbitrary Tk widgets)
  • Screenshot — no WebView capture API; wry 0.56.1 does not expose one yet (wry#1674). tkwry will wrap it when upstream ships; no JS fallback (see Platform notes)
  • Find in page — no find / find_next / find_previous / clear_find; wry has none (wry#585). Do not treat window.find as a Capability. See Platform notes — Find in page

See CHANGELOG.md for release history.


🌐 Platform notes

Pre-built wheels: Windows and macOS. Linux is source-only (best-effort).

OS Arch Parent handle Engine
Windows x86_64, arm64 Frame.winfo_id() → HWND WebView2
macOS arm64, x86_64 Toplevel content NSView WKWebView
Linux — winfo_id() → X11 window ID WebKitGTK

DPI, WebView2, macOS embedding / IME / import order, and Linux eval caveats: Platform notes.


💡 Why child-window embedding?

Tkinter apps already have a window and a layout. The web belongs inside a Frame — same mainloop, same tabs and panes — not in a separate top-level webview that floats beside your UI. tkwry wraps wry's build_as_child against the native surface Tk gives your widgets.


🧩 Features

  • Local app assets — app= + tkwry:// (SPA fallback, app_dev no-store, ETag/HEAD/Range, default CSP, optional COOP/CORP, bounded watch_app(); open-then-verify symlink/junction confinement)
  • IPC / RPC / emit — events vs request/response; sync-generator stream; worker RPC; typed TypeError; protocol version; JS cancel; Python→JS emit; origin/path allowlist (bridge_origins) + bridge_allow + untrusted= viewer mode
  • WebSession — shared wry WebContext; Cookie CRUD on WebView (cookies / set_cookie / …); shared app= roots must match; emit_all broadcast
  • Testing helpers — tkwry.testing.wait_until / wait_ready / wait_eval / wait_title
  • Child-window embedding — WebView is a native child of your Tk window surface, not a floating overlay
  • Bounds & visibility sync — follows <Configure>, <Map>, and <Unmap> (tabs / Notebook hide unmapped views)
  • Typed failure signals — create: <<WebViewCreateFailed>> / when_failed; eval: <<WebViewEvalFailed>> / WebViewTimeoutError; nav hook timeout: <<WebViewNavigationFailed>> / WebViewNavigationError (native still returns the default deny); downloads: <<WebViewDownloadComplete>> / <<WebViewDownloadFailed>> / last_download
  • Deferred callbacks — IPC, RPC, page load, title, eval results, and DnD queue to Tk (avoids macOS deadlocks)
  • URL safety — Python load_url normalizes/validates schemes; in-page nav denies javascript:/blob:/… (data: under app=); app= stays on tkwry://; IPC/RPC origin/path allowlist + bridge_allow
  • DevTools — devtools=True at create, then open_devtools() / close_devtools() / is_devtools_open(); Windows: open works, close/is_devtools_open limited (see Platform notes — DevTools); macOS: private APIs
  • Print — web.print() opens the system print dialog (no PDF / no result)
  • Downloads — on_download / on_download_complete + download_allow; untrusted=True denies unless permitted; last_download + <<WebViewDownloadComplete>> / <<WebViewDownloadFailed>>; unique_download_path for same-name files (absolute dest only; no overwrite policy)
  • Native drag & drop — OS-level file drops into the WebView (no tkinterdnd2)
  • Navigation hooks — all handlers on the Tk thread; on_navigation / on_new_window block WebKit until they return
  • Multiple layouts — works with pack, grid, place, Notebook, and PanedWindow (see examples)
  • Plotly-ready — load HTML + eval_js; demo toggles CDN vs local app=
  • Folium-ready — embed Leaflet maps from Folium HTML (right-click to pin)
  • Markdown-ready — Monaco editor + live preview in a PanedWindow (see examples/markdown_demo.py; CDN required — or vendor under app=)
  • CI-tested — pytest on Windows (x86_64 + arm64), macOS, and Linux (Xvfb + WebKitGTK)

📁 Examples

python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
Script Description
examples/browser_demo.py URL bar, tabs, shared WebSession, print / downloads / emit_all (bridge_origins="*"; no expose)
examples/ipc_demo.py IPC events, RPC (call / kwargs / worker), stream (ticks + cancel), and emit
examples/multi_demo.py Multiple WebViews, tabs, panes; emit_all flash
examples/plotly_demo.py Plotly charts — CDN or local app= (pip install plotly)
examples/folium_demo.py Folium maps (pip install folium; tiles need the network)
examples/markdown_demo.py Monaco markdown editor + live preview (CDN)
examples/dnd_demo.py Native file drag & drop into WebView
python examples/browser_demo.py
python examples/ipc_demo.py
python examples/multi_demo.py
python examples/plotly_demo.py
python examples/folium_demo.py
python examples/markdown_demo.py
python examples/dnd_demo.py

📝 License

This project is licensed under the MIT License. See LICENSE.

This project links against wry, which is dual-licensed (Apache-2.0 or MIT). tkwry uses wry under MIT; see NOTICE for attribution.


👨‍💻 Author

mashu3

Contributors

Metadata

Release files for tkwry 0.1.7

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

Source distribution (sdist)

Source distribution for tkwry 0.1.7
File Size Uploaded
tkwry-0.1.7.tar.gz 340.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for tkwry 0.1.7
File
tkwry-0.1.7-cp310-abi3-win_arm64.whl CPython 3.10 abi3 Windows ARM64 Details
tkwry-0.1.7-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
tkwry-0.1.7-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
tkwry-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 3.1 MB

Release files / tkwry-0.1.7.tar.gz

Download URL tkwry-0.1.7.tar.gz
Size 340.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b26223e803b1fa144f6c9c245419f7ef841dede7dd4ea394463ad15e5a6c5b08
BLAKE2b-256 checksum
How to use checksums
b709edf9888b8ffff004295a75ab9e47ad0abd28b68f9974a1209bf8ae01856d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release files / tkwry-0.1.7-cp310-abi3-win_arm64.whl

Download URL tkwry-0.1.7-cp310-abi3-win_arm64.whl
Size 588.1 kB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
2985af62dc38a5b62dbf181544801f297aa1cde7d92062275d3c2c6a535ee380
BLAKE2b-256 checksum
How to use checksums
1c6acfd534d9e1e2c313483debb0260af83751a34d1521a10c1a41789a7ce387
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release files / tkwry-0.1.7-cp310-abi3-win_amd64.whl

Download URL tkwry-0.1.7-cp310-abi3-win_amd64.whl
Size 608.2 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
f71f87307de415dd5c05dcfab056e0d8bd07b319d8fe464d96e4cd166bc28369
BLAKE2b-256 checksum
How to use checksums
be6e356885cc1580f9efb0f4d6d3608599575df5b1ca6a14a8a6f1a3201dddf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release files / tkwry-0.1.7-cp310-abi3-macosx_11_0_arm64.whl

Download URL tkwry-0.1.7-cp310-abi3-macosx_11_0_arm64.whl
Size 779.0 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2d9b222f9ea472e3395017f52fb3c3e710a24345a1c90d20a32f9cbf3948b5f2
BLAKE2b-256 checksum
How to use checksums
1eb9b9f2d56fa25652fd5fa99d2d2a771ceb4506758429efeeb6b118057fb473
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release files / tkwry-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl

Download URL tkwry-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl
Size 811.2 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
9fb00434be1a1e13c3379e76e3fd909f5287b41cf4e6c049f9a578164f5b3b2e
BLAKE2b-256 checksum
How to use checksums
cb65d905a2b07805ffe48d24a0c5dec91f7951ef349f14a59878a2471b0ffe9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.9

5 release files

0.1.8

5 release files

This release

0.1.7 This release

5 release files

0.1.6

5 release files

0.1.5

5 release files

0.1.4

5 release files

0.1.3

5 release files

0.1.2

5 release files

0.1.1

5 release files

0.1.0

5 release files

0.0.9

5 release files

0.0.8

5 release files

0.0.7

5 release files

0.0.6

5 release files

0.0.5

4 release files

0.0.4

4 release files

0.0.3

4 release files

0.0.2

4 release files

0.0.1

4 release files

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