Skip to main content

aiowx

Bridge wxPython with Python asyncio — run async/await coroutines in your wx GUI.

PyPI Python CI

Installation

As a dependency

uv add aiowx
# or with pip:
pip install aiowx

From source

git clone https://github.com/Row0902/aiowx.git
cd aiowx
uv sync          # install deps + dev deps
uv build         # build wheel + source dist

Requires Python 3.12+, wxPython ≥ 4.2.5, and uv.


Quick start

import asyncio
import wx
from aiowx import AsyncBind, WxAsyncApp, StartCoroutine


class CounterFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="aiowx counter")
        self.label = wx.StaticText(self, label="0")
        btn = wx.Button(self, label="+1")

        AsyncBind(wx.EVT_BUTTON, self.on_click, btn)
        StartCoroutine(self.tick, self)

    async def on_click(self, _event):
        self.label.SetLabel(str(int(self.label.GetLabel()) + 1))

    async def tick(self):
        while True:
            self.label.SetLabel(str(int(self.label.GetLabel()) + 1))
            await asyncio.sleep(1)


async def main():
    app = WxAsyncApp()
    frame = CounterFrame()
    frame.Show()
    app.SetTopWindow(frame)
    await app.MainLoop()


asyncio.run(main())

API

Function Purpose Async
WxAsyncApp() Drop-in replacement for wx.App —
await app.MainLoop() Start the event loop ✅
AsyncBind(event, coro, widget) Bind a wx event to a coroutine —
StartCoroutine(coro, window) Fire a coroutine attached to a window —
await AsyncShowDialog(dlg) Show a dialog modally (modless path) ✅
await AsyncShowDialogModal(dlg) Show an OS dialog safely ✅

WxAsyncApp

Create instead of wx.App. Interleaves the wx event loop with asyncio so both GUI events and coroutines run cooperatively.

app = WxAsyncApp()
await app.MainLoop()

AsyncBind

Bind a wx event to an async callback. Works alongside regular wx.Bind.

AsyncBind(wx.EVT_BUTTON, on_submit, submit_btn)

async def on_submit(event):
    result = await fetch_data()       # non-blocking I/O
    display.SetLabel(f"Got: {result}")

StartCoroutine

Run a coroutine immediately, attached to a wx.Window. It is automatically cancelled when the window is destroyed — no manual cleanup.

task = StartCoroutine(poll_sensor(sensor), panel)
# ...
task.cancel()   # optional early cancel

AsyncShowDialog / AsyncShowDialogModal

Show dialogs without blocking the event loop.

  • AsyncShowDialog: works with custom dialogs (modless path).
  • AsyncShowDialogModal: for OS-native dialogs (wx.FileDialog, wx.DirDialog, etc.). Runs on the wx main thread (thread-safe).
async def pick_file(parent):
    dlg = wx.FileDialog(parent)
    result = await AsyncShowDialogModal(dlg)
    if result == wx.ID_OK:
        path.SetLabel(dlg.GetPath())

Note: the asyncio event loop is blocked while the modal dialog is open. This is expected desktop GUI behavior — identical to how ShowModal works in a traditional wx app.


Patterns

Background task with cancellation

import asyncio
from aiowx import StartCoroutine


class MonitorFrame(wx.Frame):
    def __init__(self):
        super().__init__(None)
        self.running = True
        self.task = StartCoroutine(self.watchdog, self)

    async def watchdog(self):
        while self.running:
            await asyncio.sleep(5)
            if not self.check_health():
                wx.MessageBox("Connection lost")
                break

Dialog with await

async def save_file(parent):
    dlg = wx.FileDialog(
        parent,
        style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
    )
    if await AsyncShowDialogModal(dlg) == wx.ID_OK:
        with open(dlg.GetPath(), "w") as f:
            f.write(data)

Performance

Values measured on Windows (Core i7-7700K @ 4.2 GHz):

Scenario Latency Latency at max throughput Max throughput
asyncio only (reference) 0 ms 17 ms 571 325 msg/s
wx only (reference) 0 ms 19 ms 94 591 msg/s
aiowx (GUI) 5 ms 19 ms 52 304 msg/s
aiowx (GUI + asyncio) 5 ms / 0 ms 24 ms / 12 ms 40 302 + 134 000 msg/s

CPU usage at idle: 0% on Windows, ~1–2% on macOS.


Requirements

  • Python ≥ 3.12
  • wxPython ≥ 4.2.5 (4.2.5+ includes Python 3.14 wheels)

Repository

https://github.com/Row0902/aiowx

Metadata

Release files for aiowx 0.3.0

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

Source distribution (sdist)

Source distribution for aiowx 0.3.0
File Size Uploaded Provenance Actions
aiowx-0.3.0.tar.gz 7.3 kB Without provenance Details for aiowx-0.3.0.tar.gz

Built distribution (wheel)

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

Total release size: 14.9 kB

Release files / aiowx-0.3.0.tar.gz

Download URL aiowx-0.3.0.tar.gz
Size 7.3 kB
Tags Source
SHA-256 checksum
How to use checksums
87b16239f5b7ba32fa1f75efadac334cfa0d9a319bed7f7e4f8d31dc054f9ef8
BLAKE2b-256 checksum
How to use checksums
777d8a9d8800eb16a574057327e92a0e06d8016b2273bc38e8034240c46a1a02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / aiowx-0.3.0-py3-none-any.whl

Download URL aiowx-0.3.0-py3-none-any.whl
Size 7.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
242098ae57b10fa0bc1b93e721ea818a4e6723bbf3829e203ac86920cd0ea124
BLAKE2b-256 checksum
How to use checksums
69bebad889f893b16e36badc863acb5bc8240b124097a025af6f23f89d7f50f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for aiowx 0.3.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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