Repository navigation
Security and Escaping
oldmangan edited this page Oct 6, 2026
·
1 revision
wapyt renders model output, remote data and user input, so these rules matter.
| API | Inserts | Your job |
|---|---|---|
Layout.attach_html, CellConfig(html=...)
|
raw HTML |
html.escape(value, quote=True) every interpolated value |
TabConfig(html=...), TabWidget.attach_html
|
raw HTML | same |
ModalWindow.set_content(markup) |
raw HTML | same |
ResourceBoardConfig.detail_template |
escaped {placeholders}
|
nothing, unless you use a …Html key, which is raw |
| CardPanel descriptor templates | escaped into html; text is set as text |
nothing |
| Widget labels, titles, cells, tree nodes, form values | text | nothing |
- Widgets put text into the DOM with
textContent. Markup usesinnerHTMLonly withescapeHtml()on every interpolated value. - Chat renders markdown with its own escaping renderer. It uses
markedonly whenDOMPurifyis also on the page, becausemarkedpasses raw HTML through. - Chat artifact chips are the one unescaped fragment, and carry a per-widget nonce, so model output that only looks like a chip is still escaped.
- Artifact previews run in
<iframe sandbox="allow-scripts">. Never addallow-same-origin: withallow-scriptsit cancels the sandbox.
Form validation helps the person typing. The BFF must revalidate everything
it receives; show its errors with form.set_error(...).
pyTincture denies microphone and camera by default
(Permissions-Policy: microphone=()). Chat voice input needs
PYTINCTURE_ALLOW_MICROPHONE=1 and a secure context.
wapyt is MIT-licensed · Repository · pyTincture · Issues
Getting started
Widgets
- Layout and MainWindow
- Tree
- DataTable
- Form
- ModalWindow
- Window
- TabWidget
- Toolbar
- Sidebar
- Chat
- Terminal
- CardPanel
- ResourceBoard
- File Transfer
- Message
- ContextMenu
- MenuBar
- Listbox
- Kanban
- ProgressBar
- Pagination
- Popup and tooltips
- Chart
- Scheduler
- MediaPlayer
Guides
Planning
Contributing