Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Python bindings

The reticle-py crate exposes the document and layout-generator APIs to Python through PyO3. It is a native extension built with maturin as a stable-ABI (abi3) wheel, so one wheel loads on every CPython 3.9 and later. The package is a mixed Rust and Python project: the compiled module is imported as reticle_py._core, and a small pure Python layer re-exports it and adds a Jupyter inline viewer.

reticle-py is native only and is deliberately not part of the default Cargo workspace, so the just ci gate never needs a Python toolchain. The reasoning is recorded in ADR 0087.

API surface

import reticle_py as rp

rp.version()                       # crate version string
rp.generators()                    # list of {id, title, description} dicts

doc = rp.Document.open("design.gds")   # GDSII, OASIS, CIF, or DXF; content-sniffed, extension is a fallback
doc.cell_names()                   # sorted list of cell names
doc.top_cells()                    # the document's top (root) cells
doc.cell_count()                   # number of cells
doc.summary()                      # dict of counts, top cells, and layers in use
doc.shapes("TOP")                  # list of {layer, datatype, kind, bbox} for a cell

# Place a built-in generator by id with JSON parameters. Empty "{}" uses the
# generator's own defaults. Returns {shapes_added, bbox}.
doc.place_generator("TOP", "guard_ring", "{}")

png = doc.render_png("TOP", 800, 600)   # PNG bytes, or None if no GPU is available
doc.save("out.gds")                     # format inferred, or pass "gds" / "oasis"

Everything that crosses the boundary is treated as untrusted and validated before it reaches native code: render dimensions must be between 1 and 16384 on each axis, cell names are checked against the document (a miss raises KeyError), and generator parameters are parsed and range-checked by the registry, which reports the offending field as a ValueError.

The Jupyter widget

The v1 viewer renders a cell to a PNG with the same offscreen GPU path the CLI uses and displays it inline:

rp.show(doc, "TOP", width=640, height=480)     # inline image, or a note if no GPU

rp.LayoutView(doc, "TOP") is a lazy alternative whose _repr_png_ renders when a notebook displays it, falling back to a text representation when no GPU adapter is present. A richer interactive widget (browser pan and zoom) is a follow-up; an image is enough to see a layout today.

The committed example notebook, crates/reticle-py/examples/reticle_intro.ipynb, opens the bundled basic.gds, lists the generators, places a guard ring, renders the cell, and saves the result.

Building the wheel

The build runs maturin under uv:

uv tool install maturin
cd crates/reticle-py
maturin build --release        # writes a wheel under the shared target's wheels/ dir

For local development against the current interpreter, maturin develop builds and installs the extension into the active virtual environment in one step.