Custom Jupyter widgets made easy with modern web technologies and seamless platform integration
npx @tessl/cli install tessl/pypi-anywidget@0.9.0A comprehensive toolkit for creating reusable, interactive web-based widgets for Jupyter environments without requiring complex cookiecutter templates. anywidget enables developers to build custom Jupyter widgets using modern web technologies and provides seamless integration across multiple platforms including Jupyter, JupyterLab, Google Colab, VSCode, and marimo.
pip install anywidgetimport anywidgetMost common usage:
from anywidget import AnyWidgetFor experimental features:
from anywidget.experimental import widget, dataclass, MimeBundleDescriptorimport anywidget
import traitlets as t
# Basic widget with inline ES module
class CounterWidget(anywidget.AnyWidget):
_esm = """
function render({ model, el }) {
let count = () => model.get("value");
let btn = document.createElement("button");
btn.innerHTML = `count is ${count()}`;
btn.addEventListener("click", () => {
model.set("value", count() + 1);
});
el.appendChild(btn);
model.on("change:value", () => {
btn.innerHTML = `count is ${count()}`;
});
}
export default { render };
"""
value = t.Int(0).tag(sync=True)
# Create and display the widget
widget = CounterWidget()
widget # In Jupyter, this displays the widgetanywidget provides a flexible architecture for creating custom Jupyter widgets:
The system supports multiple widget creation patterns: class-based inheritance, decorator-based composition, and dataclass-based reactive widgets, making it suitable for simple prototypes to complex interactive applications.
The fundamental AnyWidget base class that provides the foundation for creating custom Jupyter widgets with ES modules and CSS styling.
class AnyWidget(ipywidgets.DOMWidget):
def __init__(*args, **kwargs): ...
def __init_subclass__(**kwargs): ...
def _repr_mimebundle_(**kwargs): ...Advanced decorator-based patterns for creating widgets using modern Python features including dataclasses, event systems, and function-based approaches.
def widget(*, esm: str | Path, css: str | Path | None = None, **kwargs): ...
def dataclass(cls=None, *, esm: str | Path, css: str | Path | None = None, **dataclass_kwargs): ...Dynamic file loading system with live reloading capabilities for development workflows and virtual file management for inline content.
class FileContents:
def __init__(path: str | Path, start_thread: bool = True): ...
def __str__() -> str: ...
class VirtualFileContents:
def __init__(contents: str = ""): ...
def __str__() -> str: ...Cell magic support for creating virtual files and managing widget development workflows within Jupyter notebooks.
def load_ipython_extension(ipython): ...
class AnyWidgetMagics:
def vfile(line: str, cell: str): ...
def clear_vfiles(line: str): ...# Core widget types
class AnyWidget(ipywidgets.DOMWidget):
"""Main widget base class"""
_model_name: str
_model_module: str
_model_module_version: str
_view_name: str
_view_module: str
_view_module_version: str
# File content types
class FileContents:
"""File watcher with change signals"""
changed: Signal
deleted: Signal
class VirtualFileContents:
"""In-memory file contents with change signals"""
changed: Signal
contents: str
# Descriptor types
class MimeBundleDescriptor:
"""Descriptor for widget representation"""
def __init__(*, follow_changes: bool = True, autodetect_observer: bool = True, no_view: bool = False, **extra_state): ...
class ReprMimeBundle:
"""Widget representation with comm management"""
def send_state(include: str | list[str] | None = None): ...
def sync_object_with_view(py_to_js: bool = True, js_to_py: bool = True): ...
def unsync_object_with_view(): ...
# Protocol types
class WidgetBase(Protocol):
"""Base widget protocol for custom messages"""
def send(msg: str | dict | list, buffers: list[bytes]): ...
def on_msg(callback): ...