Skip to main content

microui-py

A Python wrapper for the microui immediate-mode UI library

Python 3.10+ MIT License CI

microui-py provides Python bindings for microui, a tiny (~1100 SLOC) portable immediate-mode UI library written in ANSI C. This wrapper allows you to create lightweight, responsive user interfaces in Python while maintaining the performance and simplicity of the original C library.

Note: Earlier iterations of microui-py were created with the intent to contribute the python wrapper back into the original microui project. However, it is now clear that the author of microui is not accepting PRs and wants to keep the project miminal. While this is fair enough, it was decided to move pymui to its own repo to develop it independently and possibly track other active forks which may emerge.

Features

  • Pythonic API - Clean, intuitive Python interface

  • High Performance - Direct Cython bindings to C library

  • Immediate Mode - No retained widget objects, simple state management

  • Flexible Layout - Dynamic row-based layout system

  • Customizable - Full control over styling and rendering

  • Memory Safe - Comprehensive bounds checking and error handling

  • Easy Integration - Bundled SDL2/OpenGL app loop, or feed draw commands to your own renderer

  • Unicode Text - Load any TrueType/OpenType font with pymui.load_font()

screenshot

Upgrading from 0.2

0.3.0 changes behavior that 0.2 code may rely on. Full list in the CHANGELOG.

  • The PyPI distribution is microui-py (pip install microui-py); import pymui is unchanged.

  • textbox(text, bufsz) returns (result, text); it was a stub returning 0.

  • draw_text(text, pos, color) lost its unused font argument.

  • Two widgets with the same ID in one frame raise DuplicateIDError. Repeated labels need key= or ctx.id_scope().

  • Misuse that used to crash the interpreter raises RuntimeError or ValueError; see Errors Instead of Aborts.

  • Color channels outside 0..255 raise instead of wrapping.

Quick Start

Installation

The distribution is named microui-py; the import name is pymui.

pip install microui-py     # abi3 wheels for CPython 3.12+; 3.10/3.11 build from source
import pymui

From a clone, for development:

git clone https://github.com/shakfu/pymui.git
cd pymui
uv sync --dev
make build                 # editable build of the extension

Basic Usage

import pymui

# Recommended: Use context managers for both frame and window management
with pymui.Context() as ctx:
    # Window context manager (automatically calls begin_window/end_window)
    with ctx.window("My Window", 10, 10, 200, 150) as window:
        if window.is_open:
            # Create a button
            if ctx.button("Click me!"):
                print("Button was clicked!")

            # Create a checkbox
            result, checked = ctx.checkbox("Enable feature", True)

            # Create a slider
            result, value = ctx.slider(50.0, 0.0, 100.0)

# Alternative: Manual window management
with pymui.Context() as ctx:
    if ctx.begin_window("Manual Window", pymui.Rect(10, 10, 200, 150)):
        # UI elements here...
        ctx.end_window()

# Legacy: Manual frame management
ctx = pymui.Context()
ctx.begin()
try:
    # UI code here...
    pass
finally:
    ctx.end()

Core Concepts

Immediate Mode UI

microui-py follows the immediate-mode paradigm where UI elements are created and processed every frame:

# No widget objects to manage - just call functions each frame
for frame in main_loop():
    with pymui.Context() as ctx:  # Automatic begin/end
        # UI is rebuilt each frame
        if ctx.button("Dynamic Button"):
            handle_click()

    render_frame(ctx)

Context Manager vs Manual Frame Management

microui-py supports both automatic and manual frame management:

# Recommended: Context Manager (Automatic)
with pymui.Context() as ctx:
    # begin() called automatically
    if ctx.button("Safe Button"):
        print("Clicked!")
    # end() called automatically, even on exceptions

# Manual Management (Advanced)
ctx = pymui.Context()
ctx.begin()
try:
    if ctx.button("Manual Button"):
        print("Clicked!")
finally:
    ctx.end()  # Must always call end()

Benefits of Context Manager:

  • Automatic cleanup - end() always called, even on exceptions

  • Cleaner code - No need to remember begin/end pairs

  • Exception safety - Proper cleanup guaranteed

  • Pythonic - Follows Python's context manager idiom

Context Manager Best Practices

# Good: Use context manager for each frame
def render_frame():
    with pymui.Context() as ctx:
        # All UI code here
        if ctx.begin_window("Window", pymui.rect(10, 10, 200, 150)):
            ctx.label("Hello!")
            ctx.end_window()

# Good: Exception handling is automatic
def risky_ui_operation():
    with pymui.Context() as ctx:
        if ctx.begin_window("Risk", pymui.rect(10, 10, 200, 150)):
            if some_condition():
                raise ValueError("Something went wrong")
            ctx.label("This might not execute")
            ctx.end_window()
        # ctx.end() called automatically even if exception occurs

# Avoid: Manual management without proper exception handling
def bad_manual_approach():
    ctx = pymui.Context()
    ctx.begin()
    # If exception occurs here, end() won't be called!
    risky_operation()
    ctx.end()

# Better: Manual with proper exception handling
def good_manual_approach():
    ctx = pymui.Context()
    ctx.begin()
    try:
        risky_operation()
    finally:
        ctx.end()  # Always called

Window Context Manager

microui-py provides an additional context manager for windows that automatically handles begin_window() and end_window() calls:

# Recommended: Window context manager
with pymui.Context() as ctx:
    with ctx.window("My App", 10, 10, 300, 200) as window:
        if window.is_open:
            ctx.label("Content goes here")
            if ctx.button("Click me"):
                print("Button clicked!")
        # end_window() called automatically

# Alternative: Manual window management
with pymui.Context() as ctx:
    if ctx.begin_window("Manual", pymui.Rect(10, 10, 300, 200)):
        ctx.label("Content goes here")
        ctx.end_window()  # Must remember to call this

# Multiple windows with context managers
with pymui.Context() as ctx:
    with ctx.window("Window 1", 10, 10, 200, 150) as w1:
        if w1.is_open:
            ctx.label(f"Window: {w1.title}")

    with ctx.window("Window 2", 220, 10, 200, 150) as w2:
        if w2.is_open:
            ctx.label(f"Size: {w2.rect.w}x{w2.rect.h}")

Window Context Manager Benefits:

  • Automatic cleanup - end_window() always called

  • Exception safety - Cleanup on errors

  • Window state access - window.is_open, window.title, window.rect, window.opt

  • Cleaner code - No manual begin/end window pairs

  • Convenient API - ctx.window(title, x, y, w, h, opt=0)

Layout System

microui-py uses a flexible row-based layout system:

with pymui.Context() as ctx:
    if ctx.begin_window("Layout Demo", pymui.Rect(10, 10, 300, 200)):
        # Two columns: 100px wide, remaining space
        ctx.layout_row([100, -1], 25)

        ctx.label("Name:")
        result, name = ctx.textbox("", 64)

        # Three equal columns
        ctx.layout_row([80, 80, 80], 25)

        if ctx.button("OK"):
            print("OK clicked")
        if ctx.button("Cancel"):
            print("Cancel clicked")
        if ctx.button("Help"):
            print("Help clicked")

        ctx.end_window()

State Management

Since immediate-mode UIs rebuild every frame, you manage state in your application:

class AppState:
    def __init__(self):
        self.counter = 0
        self.text = ""
        self.enabled = True

state = AppState()

def update_ui():
    with pymui.Context() as ctx:
        with ctx.window("Counter", 10, 10, 200, 100) as window:
            if window.is_open:
                ctx.label(f"Count: {state.counter}")

                if ctx.button("Increment"):
                    state.counter += 1

                result, state.enabled = ctx.checkbox("Enabled", state.enabled)

Complete Example: Todo App

pymui.app.App owns the SDL window, event translation, and rendering. Override frame(ctx); it runs between ctx.begin() and ctx.end().

import pymui
from pymui.app import App

class TodoApp(App):
    def __init__(self):
        super().__init__("Todo", 640, 480)
        self.todos = ["Learn microui-py", "Build an app"]
        self.new_todo = ""

    def frame(self, ctx):
        with ctx.window("Todo App", 50, 50, 400, 300) as window:
            if not window.is_open:
                return
            ctx.layout_row([-1], 25)
            ctx.label("My Todo List")

            for i, todo in enumerate(list(self.todos)):
                ctx.layout_row([-50, -1], 25)
                ctx.label(todo)
                with ctx.id_scope(i):  # "Delete" repeats; scope its ID
                    if ctx.button("Delete"):
                        self.todos.remove(todo)

            ctx.layout_row([-80, -1], 25)
            result, self.new_todo = ctx.textbox(self.new_todo, 128, key="new")
            if (ctx.button("Add") or result & pymui.Result.SUBMIT) and self.new_todo.strip():
                self.todos.append(self.new_todo.strip())
                self.new_todo = ""

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

App.run() blocks until the window closes or app.quit() is called. The renderer requests vsync; App(max_fps=120) (the default) caps the loop where the driver ignores it. Pass max_fps=None to disable the cap. For a custom loop, call app.step(frame) per iteration, or use pymui.render(ctx, bg) with renderer_init_window() directly.

Available Widgets

Basic Controls

# Text display
ctx.text("Hello World")
ctx.label("Label text")

# Buttons
if ctx.button("Click me"):
    print("Button pressed")

# Checkboxes
result, checked = ctx.checkbox("Enable feature", current_state)

# Sliders
result, value = ctx.slider(current_value, min_val, max_val)

# Text input
result, text = ctx.textbox(current_text, buffer_size)

Widget IDs

microui tracks hover and focus by widget ID. Buttons, checkboxes, headers and tree nodes derive the ID from their label. Sliders, number fields and textboxes have no label; their default ID comes from the calling line plus a count of earlier calls from that line in the same scope. Widgets shown conditionally elsewhere therefore do not change it.

Two widgets with the same ID in one frame would share hover, focus and clicks, so pymui raises DuplicateIDError. Typical causes are repeated labels and widgets inside a reusable helper function. Disambiguate with key= or a scope:

_, volume = ctx.slider(volume, 0, 100, key="volume")
_, on = ctx.checkbox("Enabled", on, key=("channel", i))

with ctx.id_scope(row_index):   # scope every ID inside the block
    if ctx.button("Delete"):
        ...

Layout Controls

# Windows
with ctx.window("Window Title", x, y, w, h) as win:
    if win.is_open:
        ...

# Tree nodes (collapsible sections)
with ctx.treenode("Section") as expanded:
    if expanded:
        ...

# Headers (no end call)
if ctx.header("Section Header"):
    ...

# Panels (scrollable areas)
with ctx.panel("Panel Name") as panel:
    ...

# Popups
if ctx.button("Menu"):
    ctx.open_popup("menu")
with ctx.popup("menu") as is_open:
    if is_open:
        ...

Each scope calls its end_* function even if the body raises. The begin_*/end_* methods remain available; an end_* that does not match the innermost open scope raises RuntimeError. If an exception escapes a frame, Context.__exit__ discards that frame instead of calling end().

Container fields read as copies. Assign a whole value to change one: win.rect = pymui.Rect(...), panel.scroll = pymui.Vec2(...).

Layout Functions

# Set row layout: [col1_width, col2_width, ...], row_height
ctx.layout_row([100, -1, 50], 25)  # 100px, remaining, 50px

# Set individual dimensions
ctx.layout_width(200)
ctx.layout_height(30)

# Columns
with ctx.column():
    ...

Errors Instead of Aborts

microui checks its limits with abort(), which kills the interpreter. pymui checks first and raises:

Condition Error
Widget, layout or draw call outside a window or panel RuntimeError
Mismatched end_*/pop_*, or end() with scopes open RuntimeError
More than 32 nested ID scopes, 32 clips, 16 layouts, 32 windows per frame RuntimeError
More than 48 live containers, or 48 toggled headers/tree nodes RuntimeError
Command buffer (256 KB per frame) full RuntimeError
Repeated widget ID, or a window begun twice in one frame DuplicateIDError
fmt other than one %f/%e/%g conversion ValueError
Color channel outside 0..255 ValueError

Typed text beyond microui's 31-byte per-frame buffer is delivered over the following frames.

Custom Widgets

def toggle(ctx, name, on):
    wid = ctx.get_id(name)
    r = ctx.layout_next()
    ctx.update_control(wid, r)
    if ctx.mouse_pressed & pymui.Mouse.LEFT and ctx.focus == wid:
        on = not on
    ctx.draw_control_frame(wid, r, pymui.ColorIndex.BUTTON)
    ctx.draw_control_text("ON" if on else "OFF", r, pymui.ColorIndex.TEXT,
                          pymui.Option.ALIGNCENTER)
    return on

Data Types

Core Types

# 2D Vector
pos = pymui.Vec2(x=10, y=20)
print(f"Position: {pos.x}, {pos.y}")

# Rectangle
rect = pymui.Rect(x=10, y=20, w=100, h=50)

# Color (RGBA)
color = pymui.Color(r=255, g=128, b=0, a=255)  # Orange
color = pymui.Color(255, 128, 0)  # Alpha defaults to 255

# Convenience functions
pos = pymui.vec2(10, 20)
rect = pymui.rect(10, 20, 100, 50)
color = pymui.color(255, 128, 0, 255)

Text Input

# Simple textbox
textbox = pymui.Textbox(buffer_size=128)
textbox.text = "Initial text"
current_text = textbox.text

# In UI context: pass the text in, keep what comes back
result, current_text = ctx.textbox(current_text, 128, key="name")
if result & pymui.Result.SUBMIT:
    print(f"User submitted: {new_text}")

Styling

microui-py supports comprehensive styling through the style system:

# Get current style
style = ctx.style

# Modify colors
style.set_color(pymui.ColorIndex.BUTTON, pymui.Color(100, 150, 200))
style.set_color(pymui.ColorIndex.TEXT, pymui.Color(255, 255, 255))

# Available color indices
colors = [
    pymui.ColorIndex.TEXT,
    pymui.ColorIndex.BORDER,
    pymui.ColorIndex.WINDOWBG,
    pymui.ColorIndex.TITLEBG,
    pymui.ColorIndex.BUTTON,
    pymui.ColorIndex.BUTTONHOVER,
    # ... and more
]

Building and Development

Prerequisites

  • Python 3.10 or higher

  • CMake 3.28+

  • C11 compiler (GCC or Clang; Windows is untested)

  • SDL2 development libraries, including its CMake config

  • OpenGL development libraries (Linux: libgl-dev, macOS: included)

Building from Source

git clone https://github.com/shakfu/pymui.git
cd pymui

# Install dependencies
uv sync --dev

# Build the project
make build

# Run tests
make test

# Run the demo
make demo

Development Commands

# Build
make build

# Run all tests
make test

# Run memory leak detection
make memory-test

# Run performance benchmarks
make performance-test

# Clean build artifacts
make clean

Project Structure

pymui/
├── src/pymui/          # Main Python package
│   ├── pymui.pyx      # Cython wrapper
│   ├── app.py         # SDL window and event loop
│   └── __init__.py    # Package init
├── microui/           # Vendored microui, SDL/OpenGL renderer, stb_truetype
├── tests/            # Test suite
├── examples/         # showcase.py, demo.py, context-manager demos
├── scripts/          # Leak, valgrind and benchmark tools
├── doc/              # Architecture and development guides
└── .github/          # CI workflow

Examples

File Run Shows
examples/showcase.py make showcase Every feature: widgets, stable IDs, scopes, custom widgets, layout, live guard errors, style editing, TrueType fonts
examples/demo.py make demo Port of microui's C demo
examples/context_manager_demo.py uv run python examples/context_manager_demo.py Frame context manager, printed to the console
examples/window_context_demo.py uv run python examples/window_context_demo.py Window context manager, printed to the console

tests/test_examples.py runs the first two headless, so they stay in step with the API.

Fonts and Unicode

The bundled bitmap font covers ASCII; other characters draw as a box. Load a TrueType or OpenType font for everything else:

pymui.load_font("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 15)  # path or bytes
pymui.reset_font()                                                       # back to the bitmap font

The font is global: it applies to text measurement in every Context (and so to layout) and to rendering. Characters missing from the font draw as the font's own missing-glyph box. Glyphs are rasterized on first use into a 512x512 texture shared with the icons.

Only load trusted font files. The renderer uses stb_truetype, which does not validate font tables; pymui rejects files whose table directory points past the end of the data (truncated files) but cannot make a crafted file safe.

Custom Renderers

After ctx.end(), the frame is a list of commands. pymui.render(ctx, bg) draws them with the bundled renderer; to draw them elsewhere, iterate:

def draw_frame(ctx, backend):
    ctx.reset_command_iterator()
    while (cmd := ctx.next_command()) is not None:
        if cmd.type == pymui.Command.RECT:
            backend.draw_rect(cmd.rect, cmd.color)
        elif cmd.type == pymui.Command.TEXT:
            backend.draw_text(cmd.text, cmd.pos, cmd.color)
        elif cmd.type == pymui.Command.ICON:
            backend.draw_icon(cmd.icon_id, cmd.rect, cmd.color)
        elif cmd.type == pymui.Command.CLIP:
            backend.set_clip(cmd.rect)

Layout measures text with the current pymui font, so a custom renderer should draw text with the same font and size.

Testing

make test           # all tests, headless
make memory-test    # RSS and tracemalloc growth

See doc/development.md for valgrind, AddressSanitizer and benchmark instructions.

Contributing

Setup, the checklist for adding wrapper methods, and test-writing notes are in doc/development.md. Design and the safety layer are in doc/architecture.md.

API Reference

The type stubs in src/pymui/pymui.pyi list every class, method and signature. By area:

Area Names
Frame begin, end, abort_frame, in_frame, with ctx:
Containers window, popup, panel, begin_*/end_*, open_popup, get_current_container, get_container, bring_to_front
Widgets button, checkbox, slider, number, textbox, label, text, header, treenode
Layout layout_row, layout_width, layout_height, column, layout_set_next, layout_next
IDs id_scope, push_id, pop_id, get_id, key= arguments
Custom widgets update_control, draw_control_frame, draw_control_text, draw_rect, draw_box, draw_text, draw_icon, mouse_over
Input state hover, focus, mouse_pos, mouse_delta, mouse_down, mouse_pressed, key_down, key_pressed
Input input_mousemove, input_mousedown, input_mouseup, input_scroll, input_keydown, input_keyup, input_text
Rendering render, renderer_init_window, renderer_resize, renderer_shutdown, next_command, load_font, reset_font
Events poll_event, Event, EventType
App pymui.app.App: frame, run, step, quit, handle_event

Result Flags

Bit flags; 0 means no interaction.

pymui.Result.ACTIVE   # Widget is active
pymui.Result.SUBMIT   # Widget was submitted (Enter key, etc.)
pymui.Result.CHANGE   # Widget value changed

Options

pymui.Option.ALIGNCENTER   # Center-align content
pymui.Option.ALIGNRIGHT    # Right-align content
pymui.Option.NOINTERACT    # Disable interaction
pymui.Option.NOFRAME       # Don't draw frame
pymui.Option.NORESIZE      # Disable resizing
pymui.Option.NOSCROLL      # Disable scrolling
pymui.Option.NOCLOSE       # Disable close button
pymui.Option.NOTITLE       # Don't draw title
pymui.Option.HOLDFOCUS     # Hold focus
pymui.Option.AUTOSIZE      # Auto-size to content
pymui.Option.POPUP         # Popup window
pymui.Option.CLOSED        # Window is closed
pymui.Option.EXPANDED      # Header is expanded

Troubleshooting

Common Issues

Import Error: ImportError: cannot import name 'pymui'

# Make sure you've built the project
make build

# Check that build artifacts exist
ls src/pymui/pymui.*.so

RuntimeError or DuplicateIDError from a widget call: pymui checks microui's preconditions and raises instead of letting microui abort. See Errors Instead of Aborts.

Fatal error: ... assertion ... failed from microui: a precondition pymui does not check yet. Please report it with the call that triggered it.

Non-ASCII text draws as boxes: the bundled font is ASCII-only; call pymui.load_font() (see Fonts and Unicode).

Getting Help

License

microui-py is released under the MIT License. See LICENSE for details.

The underlying microui library is also MIT licensed.

Acknowledgments

  • rxi for creating the excellent microui library

  • The Cython team for making Python-C integration seamless

  • Contributors and testers who helped improve microui-py


Happy UI building with microui-py! 🎨🐍

Metadata

Release files for microui-py 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 microui-py 0.3.0
File Size Uploaded
microui_py-0.3.0.tar.gz 1.2 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for microui-py 0.3.0
File
microui_py-0.3.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
microui_py-0.3.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
microui_py-0.3.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details
microui_py-0.3.0-cp312-abi3-macosx_11_0_x86_64.whl CPython 3.12 abi3 macOS 11.0+ x86-64 Details
microui_py-0.3.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details

Total release size: 5.8 MB

Release files / microui_py-0.3.0.tar.gz

Download URL microui_py-0.3.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
acfd3d615e441926a3c0bdc0f5ac46e22f7a8b87bc91962867df72bee1d95511
BLAKE2b-256 checksum
How to use checksums
89cb5e1c23d99332c0cf50374971ff99875ca8b9aed776544386f94c5d3465ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / microui_py-0.3.0-cp312-abi3-win_amd64.whl

Download URL microui_py-0.3.0-cp312-abi3-win_amd64.whl
Size 860.1 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
fca993e844b31ebdb624952dbf2737b17cab8c37a00545a55a314d4d3ebc38ec
BLAKE2b-256 checksum
How to use checksums
ef71162969eb59fe81d8ba61e684f9bb3f1119798927836cbfc51b720c203504
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / microui_py-0.3.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL microui_py-0.3.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.1 MB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
5485441282d9f0f85997aea871fb7686b97171ad1fce41f7413561a91133af41
BLAKE2b-256 checksum
How to use checksums
0d28adaa1e47ef7bba703a6dde22f5aadc1f74f4ed73aae9cff01e0335ba5f24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / microui_py-0.3.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL microui_py-0.3.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 1.0 MB
Tags CPython 3.12 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
dd199d45f1bb9bff7ec8a5971268871c0d496e39430a8ce5a2979bf561730577
BLAKE2b-256 checksum
How to use checksums
2aa62c50c177c258f9ed0f507a7db06c0650bc99397e4e5afa93f67c63110f8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / microui_py-0.3.0-cp312-abi3-macosx_11_0_x86_64.whl

Download URL microui_py-0.3.0-cp312-abi3-macosx_11_0_x86_64.whl
Size 843.2 kB
Tags CPython 3.12 abi3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
03dedeb32c4b4a743905fbb57f39a09b6ae7f167aae1f9b30153a51181c5179b
BLAKE2b-256 checksum
How to use checksums
6c6c9e3ef950043e533b180134a6931b7e89040aa2661ca8b18423bf7561a004
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / microui_py-0.3.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL microui_py-0.3.0-cp312-abi3-macosx_11_0_arm64.whl
Size 752.5 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0f7b14ca0ef048d2b46e3e936fdf628f0d4495f46a24415d0a2175371ee22194
BLAKE2b-256 checksum
How to use checksums
7948d8765d4ac4630b69b337b1c6f4c950a6bfbf4692ee9b1e861283fbae8a46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

0.3.0 This release

6 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