Skip to content
Feeding a clanker? Grab this page as raw .md

Excalidraw API#

Bases: AnyWidget

An embedded Excalidraw whiteboard.

Draw shapes, arrows, text, and freehand sketches on an infinite canvas. The current drawing is kept in memory on the scene traitlet as an Excalidraw scene dict (elements / appState / files). Like the other drawing widgets, nothing is written to disk automatically — call :meth:save when you want to persist, and load with :meth:from_file.

Parameters:

Name Type Description Default
scene Optional[dict]

Optional Excalidraw scene dict to preload the canvas with.

None
height int

Canvas height in pixels.

DEFAULT_HEIGHT
sync_throttle_ms int

Minimum delay between syncing edits back to Python.

1000
theme str

"light" (default) or "dark". Set it to "" to instead follow the notebook's theme.

'light'
Example
import marimo as mo
from wigglystuff import Excalidraw

draw = mo.ui.anywidget(Excalidraw())
draw

After sketching something:

draw.save("diagram.excalidraw")          # write to disk
again = Excalidraw.from_file("diagram.excalidraw")  # load it back
Source code in wigglystuff/excalidraw.py
def __init__(
    self,
    scene: Optional[dict] = None,
    height: int = DEFAULT_HEIGHT,
    sync_throttle_ms: int = 1000,
    theme: str = "light",
    **kwargs,
):
    super().__init__(**kwargs)
    self.height = height
    self.sync_throttle_ms = sync_throttle_ms
    self.theme = theme
    if scene is not None:
        self.scene = scene

from_file classmethod #

from_file(path: Union[str, Path], **kwargs) -> Excalidraw

Create an :class:Excalidraw preloaded with the scene at path.

Source code in wigglystuff/excalidraw.py
@classmethod
def from_file(cls, path: Union[str, Path], **kwargs) -> "Excalidraw":
    """Create an :class:`Excalidraw` preloaded with the scene at ``path``."""
    scene = json.loads(Path(path).read_text(encoding="utf-8"))
    return cls(scene=scene, **kwargs)

get_image_base64 #

get_image_base64() -> str

Return the current drawing as a PNG data URL (empty if nothing drawn).

Source code in wigglystuff/excalidraw.py
def get_image_base64(self) -> str:
    """Return the current drawing as a PNG data URL (empty if nothing drawn)."""
    return self.image_base64

get_pil #

get_pil()

Return the current drawing as a PIL Image, or None if empty.

Handy for passing what you drew forward — e.g. into a multimodal model. The PNG is rendered in the browser and synced back, so it lags edits by up to sync_throttle_ms.

Source code in wigglystuff/excalidraw.py
def get_pil(self):
    """Return the current drawing as a PIL Image, or ``None`` if empty.

    Handy for passing what you drew forward — e.g. into a multimodal model.
    The PNG is rendered in the browser and synced back, so it lags edits by
    up to ``sync_throttle_ms``.
    """
    if not self.image_base64:
        return None
    import base64
    import io

    from PIL import Image

    payload = self.image_base64.split(",", 1)[-1]
    return Image.open(io.BytesIO(base64.b64decode(payload)))

get_scene #

get_scene() -> dict

Return the current Excalidraw scene as a dict.

Source code in wigglystuff/excalidraw.py
def get_scene(self) -> dict:
    """Return the current Excalidraw scene as a dict."""
    return dict(self.scene)

save #

save(path: Union[str, Path]) -> None

Write the current scene to path as a .excalidraw JSON file.

Source code in wigglystuff/excalidraw.py
def save(self, path: Union[str, Path]) -> None:
    """Write the current scene to ``path`` as a ``.excalidraw`` JSON file."""
    Path(path).write_text(self.to_json(), encoding="utf-8")

to_json #

to_json() -> str

Return the current scene serialized as a JSON string.

Source code in wigglystuff/excalidraw.py
def to_json(self) -> str:
    """Return the current scene serialized as a JSON string."""
    return json.dumps(self.scene)

Synced traitlets#

Traitlet Type Notes
scene dict Excalidraw scene (elements / appState / files).
image_base64 str PNG data URL of the drawing; read via get_pil().
theme str "light" (default) or "dark"; "" follows the notebook theme.
height int Canvas height in pixels.
sync_throttle_ms int Minimum delay between syncing edits back to Python.

Excalidraw itself is loaded from a CDN the first time the widget renders, so the widget needs network access and does not work fully offline.