pywry-orientation
When to reach for PyWry MCP tools (native webview rendering, Plotly, TradingView, AgGrid, chat) instead of writing Flask/Streamlit/Dash/Electron code. Use at…
**CRITICAL**: This mode is for widgets **embedded as iframes in external web pages**. This is **NOT** a native window. This is **NOT** Jupyter. The widget is sandboxed.
$ npx -y skills add deeleeramone/PyWry --skill iframe --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/iframeContext preview
The summary Claude sees to decide when to auto-load this skill.
**CRITICAL**: This mode is for widgets **embedded as iframes in external web pages**. This is **NOT** a native window. This is **NOT** Jupyter. The widget is sandboxed.
> **CRITICAL**: This mode is for widgets **embedded as iframes in external web pages**. > This is **NOT** a native window. This is **NOT** Jupyter. The widget is sandboxed.
You're creating widgets to be **embedded as iframes** in external pages:
❌ **NOT a native window** - No OS integration, no native dialogs ❌ **NOT Jupyter** - No kernel, no notebook context ❌ **NOT the main page** - You're embedded, constrained by parent
┌───────────────────────────────────────────────────────────────────┐
│ Parent Web Page (any origin) │
│ │
│ <iframe src="http://pywry-server:port/widget/abc123" │
│ width="100%" height="500"> │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ PyWry Widget (sandboxed) │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────┐ │ │
│ │ │ Your Content (HTML/CSS/JS) │ │ │
│ │ └───────────────────────────────────────────┘ │ │
│ │ │ │
│ │ [Toolbars, Charts, Forms, etc.] │ │
│ │ │ │
│ └───────────────────────────────────────────────────────┘ │
│ </iframe> │
│ │
│ Other page content... │
└───────────────────────────────────────────────────────────────────┘
↕ postMessage for communication# The parent controls your size
# <iframe src="..." width="600" height="400">
# Design content to fit
content = Div(
content="...",
style="width: 100%; height: 100%; overflow: auto;",
)# Screen real estate is precious
create_widget(
html=content.build_html(),
toolbars=[{
"position": "top",
"items": [
# Compact: icons only or short labels
{"type": "button", "label": "⟳", "event": "refresh"},
{"type": "toggle", "label": "Auto", "event": "auto-update"},
]
}]
)# By default, navigation stays within iframe navigate(widget_id, url="/other-view") # Still in iframe # External links may be blocked by parent # Use with caution: navigate(widget_id, url="https://external.com", external=True)
# Some browsers block downloads from iframes # Ensure download is triggered by user action # (button click, not automatic)
# Never expose secrets in URL or logs
# Use SecretInput handler - value stays server-side
create_widget(
toolbars=[{
"items": [
{"type": "secret", "label": "API Key", "event": "api-key"},
]
}]
)# Consider adding tokens to widget URLs for access control
# http://host:port/widget/{widget_id}?token={access_token}| Component | Why | |-----------|-----| | `Button` | Compact action triggers | | `Toggle` | On/off states (saves space) | | `Select` | Dropdowns (vertical space efficient) | | `Plotly` | Self-contained interactive charts |
# Widget emits events that parent can receive
# Parent listens for postMessage events
#
# Parent page JavaScript:
# window.addEventListener('message', (e) => {
# if (e.data.type === 'pywry:event') {
# console.log(e.data.event_type, e.data.data);
# }
# });# Server can send events to widget
send_event(widget_id, event_type="parent:message", data={"action": "refresh"})<iframe src="http://pywry-server:8001/widget/my-chart" width="100%" height="500" frameborder="0" loading="lazy"> </iframe>
<iframe src="http://pywry-server:8001/widget/my-chart" width="100%" height="500" frameborder="0" allow="clipboard-write; downloads" sandbox="allow-scripts allow-same-origin"> </iframe>
from pywry import PyWry
from pywry.toolbar import Div, Button, Toggle, Toolbar
app = PyWry()
# Compact content for iframe embedding
content = Div(
content="""
<div style="padding: 12px;">
<div id="status" style="margin-bottom: 12px;">Ready</div>
<div id="chart" style="height: 350px;"></div>
</div>
""",
component_id="embed-widget",
)
# Create embeddable widget
widget = app.show(
html=contenPyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.
Repo: deeleeramone/PyWry
When to reach for PyWry MCP tools (native webview rendering, Plotly, TradingView, AgGrid, chat) instead of writing Flask/Streamlit/Dash/Electron code. Use at…
Add OAuth2 authentication to PyWry apps — Google, GitHub, Microsoft, or any OIDC provider.
Autonomous PyWry application building using LLM sampling, elicitation, and progress reporting.
How an agent operates inside a PyWry chat widget — reading user messages, attachments, @-context, tool-call result cards, edit/resend, settings changes.
**STOP. THIS IS THE AUTHORITATIVE REFERENCE FOR ALL COMPONENTS.** **YOU MUST USE THE EXACT EVENT SIGNATURES DOCUMENTED HERE.** **THERE ARE NO EXCEPTIONS. NO…