pyweft-ui
Ready-made controls for PyWeft: buttons, form fields, cards, layout, tabs, tables, dialogs, toasts and more, styled and accessible out of the box. Build a good-looking app in Python without writing HTML or CSS.
<template>
<ui.Theme>
<ui.AppShell title="Orders">
<ui.Card title="New order">
<ui.Column>
<ui.TextField label="Customer" @bind="customer" required="true" />
<ui.Select label="Size" options="Small, Medium, Large" @bind="size" />
<ui.Switch label="Express delivery" @bind="express" />
</ui.Column>
<Fill name="footer">
<ui.Button variant="ghost" @click="reset">Reset</ui.Button>
<ui.Button variant="primary" icon="send" :loading="saving" @click="submit">
Place order
</ui.Button>
</Fill>
</ui.Card>
</ui.AppShell>
</ui.Theme>
</template>
<code>
from pyweft_ui import ui
customer: str = ""
size: str = "Medium"
express: bool = False
saving: bool = False
def reset(self):
self.customer, self.size, self.express = "", "Medium", False
async def submit(self):
...
</code>
New to the toolkit? Read the guide: page layout, forms with validation, dialogs, themes and building your own components, with complete examples. This README is the compact reference.
Install
It isn't on PyPI yet, so install it from GitHub, into the same environment as PyWeft itself (see PyWeft's quick start):
uv add "pyweft-ui @ git+https://github.com/prassanthn/PyWeft.git#subdirectory=packages/pyweft-ui"
With pip:
pip install "git+https://github.com/prassanthn/PyWeft.git#subdirectory=packages/pyweft-ui"
Then add "pyweft-ui" to the dependencies list in your app's own
pyproject.toml (myapp/pyproject.toml), import it in a component's code
block with from pyweft_ui import ui, and use the controls as <ui.Name>.
pyweft run and pyweft build see that it is installed locally and send it
to the browser for you.
Controls
Every control is a PyWeft component: attributes set its fields, @bind
connects it to a field of yours, and attributes it doesn't have, such as
class, style, id and aria-*, go onto its outer element. Plain
attribute values are converted to each field's type, so cols="3" is the
number 3 and disabled="true" is True.
Layout
| Control | Fields | Notes |
|---|---|---|
Theme |
mode (light, dark, auto), primary, radius, font |
Wrap your app in it to set colours and corners for everything inside. Optional. |
AppShell |
title, width (narrow, normal, wide, full) |
Header, optional sidebar and content. Fills: brand, actions, nav. |
Row |
gap, align, justify (start, center, end, between), wrap |
Children side by side. |
Column |
gap, align |
Children stacked. |
Grid |
cols, min_width, gap |
Fixed columns, or as many as fit. |
Card |
title, subtitle |
Fills: title, actions, footer. |
Gaps take none, xs, sm, md, lg, xl, or any CSS length.
Form fields
All have label, hint, error, required, disabled, name, and take
@bind.
| Control | Binds | Extra fields |
|---|---|---|
TextField |
str |
type (text, email, password, search, url, tel, date, time), placeholder, autocomplete; emits enter on Enter |
TextArea |
str |
rows, placeholder |
NumberField |
int or float |
min, max, step, placeholder |
Select |
the chosen option's value | options, placeholder |
RadioGroup |
the chosen option's value | options, inline |
Checkbox |
bool |
|
Switch |
bool |
options can be a comma-separated string ("Small, Medium, Large"), a list
of values, a list of (value, label) pairs or a list of
{"value": ..., "label": ...} dicts. The bound field gets the value itself,
so [(1, "One"), (2, "Two")] binds an int.
Data and navigation
| Control | Fields | Notes |
|---|---|---|
Tabs |
options, label, variant (line, pills) |
@bind to the chosen option's value. The content between the tags is the panel; tab inside it is the chosen value. Arrow keys, Home and End move between tabs. |
Table |
rows, columns, row_key, sortable, sort, striped, dense, caption, empty |
rows are dicts or objects. Emits select with the clicked row. Fills: cell (with row, column, value, text), empty. |
Table columns are field names ("id, customer"), (field, heading) pairs,
or dicts with key and optionally label, format (",.2f" or a
function), align and sortable. Left out, they come from the first row.
sort="-total" starts sorted by total, largest first.
Actions and feedback
| Control | Fields | Notes |
|---|---|---|
Button |
variant (primary, secondary, ghost, danger), size (sm, md, lg), icon, loading, disabled, block, type |
Emits click. |
Dialog |
title, width, dismissible |
@bind to a bool: open while it is True. Esc, a click outside or the X close it. Keeps Tab inside while open and gives focus back when closed. Fill: footer. |
Toaster |
position (bottom-right, bottom-left, bottom-center, top-left, top-center, top-right), limit |
Put one on the page; it shows what toast() raises. |
Alert |
kind (info, success, warning, danger), title, dismissible |
Emits close. |
Badge |
kind (neutral, primary, info, success, warning, danger) |
|
Spinner |
size, label |
|
Icon |
name, size |
check, x, plus, minus, search, info, alert, chevron-up/down/left/right, menu, trash, edit, send, user, home, star, heart, download, upload, external, copy, settings, sun, moon |
Toasts
from pyweft_ui import toast, clear_toasts
toast("Saved") # info, closes after 4 s
toast("Payment failed", "danger", title="Oops") # kind: info, success, warning, danger
toast("Archived", action="Undo", on_action=undo) # a button that calls undo()
note = toast("Uploading…", duration=None) # stays until note.close()
Call it from any handler or task; the page's <ui.Toaster /> shows it.
Theming
<ui.Theme mode="auto" primary="#0f766e" radius="12px">
...
</ui.Theme>
Every colour is a CSS variable (--ui-primary, --ui-text, --ui-surface,
--ui-border, --ui-danger ...), so you can also set them in your own CSS.
The gallery
gallery/ is a PyWeft app showing every control. From the PyWeft repository:
uv run pyweft run packages/pyweft-ui/gallery
Metadata
Release files for pyweft-ui 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyweft_ui-0.1.0.tar.gz | 41.6 kB | With provenance | Details for pyweft_ui-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyweft_ui-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for pyweft_ui-0.1.0-py3-none-any.whl |
Total release size: 73.3 kB
Release files / pyweft_ui-0.1.0.tar.gz
| Download URL | pyweft_ui-0.1.0.tar.gz |
|---|---|
| Size | 41.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
82810289073a9446260429f21aab0f67f841c1113296587c33822b097e071177
|
|
BLAKE2b-256 checksum How to use checksums |
f0688e6553f4c5c9eb58d21c128a30646aeb1198f556f11dcbcc2925b956dd4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 3, 2026.
Transparency logRelease files / pyweft_ui-0.1.0-py3-none-any.whl
| Download URL | pyweft_ui-0.1.0-py3-none-any.whl |
|---|---|
| Size | 31.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62cd81c6295678b4b0e5361867134665a7e4d3454b224017600c8add81f615e3
|
|
BLAKE2b-256 checksum How to use checksums |
41b99214e79f9d992ea1fc6841b58d8648f08722f5fe789eab9c4d0c4adc4392
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 3, 2026.
Transparency logSecurity for pyweft-ui 0.1.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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pyweft_ui-0.1.0.tar.gz
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 Nov 3, 2026.
Transparency logA 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.