Skip to content
h0rvPublic
forked from MrBlenny/py-d2

About

A fully typed python interface for building .d2 graph files for use with the D2 engine.

Resources

Stars

4 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

d2-python

d2-python banner

Build D2 diagrams with Python code.

D2 is a language for writing diagrams as text. d2-python lets you build that text from code, so you can draw diagrams from data, loops and functions. You describe shapes and connections as typed Python objects, and the library writes the D2 and renders it to SVG, PNG, PDF or ASCII.

This project is a maintained hard fork of MrBlenny/py-d2. See Coming from py-d2 if you used it.

Install

Add d2-python to your project with uv. The bin extra also installs the official D2 binary, so d2.render works without installing D2 yourself:

uv add 'd2-python[bin]'

Run a single script without a project:

uv run --with 'd2-python[bin]' diagram.py

Run the D2 command itself without installing anything, or install it once so d2 is on your PATH:

uvx d2-bin --version
uv tool install d2-bin

With pip, use pip install 'd2-python[bin]'. If you already have the d2 command on your PATH, you can leave out the bin extra.

Quick start

import d2

diagram = d2.Diagram(
    shapes=[
        d2.Shape(name="api", label="API"),
        d2.Shape(name="db", label="Postgres", shape=d2.ShapeType.cylinder),
    ],
    connections=[d2.Connection("api", "db", "reads and writes")],
)

print(diagram)  # the D2 text
open("graph.svg", "wb").write(d2.render(diagram))
print(d2.render(diagram, "txt").decode())  # ASCII art

print(diagram) prints this D2 text:

api: API
db: Postgres {
  shape: cylinder
}
api -> db: reads and writes

The ASCII render looks like this:

    ┌──────┐
    │ API  │
    │      │
    └──────┘
        │
reads and writes
        │
        ▼
    .-‾‾‾‾-.
   │╲-____-╱│
   │        │
   │Postgres│
   │        │
    ╲-____-╱

Building diagrams

Every feature below has a runnable script in examples/.

Shapes take a type, an icon, a tooltip and a link:

db = d2.Shape(
    name="db",
    shape=d2.ShapeType.cylinder,
    icon="https://icons.terrastruct.com/essentials%2F117-database.svg",
    tooltip="Primary database",
    link="https://example.com/runbook",
)

A shape can hold other shapes. Connect nested shapes with a dotted path:

backend = d2.Shape(
    name="backend", shapes=[d2.Shape(name="api"), d2.Shape(name="worker")]
)
d2.Connection("backend.api", "backend.worker")

Styles set colors, borders, fonts and effects:

d2.Style(fill="#dbeafe", stroke="navy", stroke_width=2, bold=True, shadow=True)

Connections take a direction, a label, a style and arrowheads, including crow's foot ends for data models:

d2.Connection(
    "orders",
    "users",
    "belongs to",
    direction=d2.Direction.TO,
    style=d2.Style(stroke="gray", animated=True),
    source_arrowhead=d2.Arrowhead(d2.ArrowheadShape.CF_MANY),
    target_arrowhead=d2.Arrowhead(d2.ArrowheadShape.CF_ONE_REQUIRED),
)

A label can be Markdown, LaTeX or code:

d2.Shape(name="notes", label=d2.Text("# Notes\nSome **bold** text", "md"))

Other features:

  • SQL tables with constraints, and UML class shapes with fields and methods.
  • Grids, with grid_rows, grid_columns and gaps.
  • Reusable style classes, set on the diagram and used by name.
  • Layers, scenarios and steps, which are extra boards in one diagram.
  • Diagram settings through d2.Config, such as the layout engine, theme and sketch mode.
  • Variables with ${name} substitution, and legends.
  • Label and icon positions, and fixed top and left positions.
  • Comments at the top of the file.

Rendering

d2.render(diagram, format) runs d2 and returns the result as bytes. It uses the binary from d2-bin when that is installed, and otherwise the d2 command on your PATH. You can also pass D2 text as a string.

Option Values
format "svg" (default), "png", "pdf", "gif", "pptx" or "txt" for ASCII
layout "dagre", "elk" or "tala"
theme, dark_theme a D2 theme id
target the board to render: the root by default, or a path such as "layers.detail"
Others sketch, pad, scale, center, omit_version, no_xml_tag, salt, animate_interval, ascii_mode, timeout

If d2 fails, render raises d2.D2Error with d2's message.

Checking and formatting D2

d2.validate runs d2 validate and raises d2.D2Error when the source is wrong. d2.fmt returns the source formatted by d2 fmt. Both take a Diagram or a string, so you can use them to check D2 text that a person or a language model wrote.

d2.validate("a -> b")
print(d2.fmt("a->b"))

validate checks the syntax and meaning of the source. It does not lay the diagram out, so a few errors only show when you render.

How values are checked

The library checks values when you create an object, so a mistake fails in your code instead of in d2.

  • Names and labels that D2 cannot read as written are quoted for you, e.g. a name with a dot or a D2 keyword such as shape. Connection endpoints are written as given, so they can be dotted paths.
  • A color can be a CSS color name, a 3 or 6 digit hex code with or without #, a gradient or a ${variable}. You can pass a string or a d2.Color. The library writes hex codes in lowercase with # and in quotes, because a bare # starts a comment in D2. Any other value raises ValueError.
  • Numbers that D2 limits are checked, e.g. opacity must be from 0 to 1.

Coming from py-d2

Import d2 instead of py_d2, and drop the D2 prefix from class names, e.g. d2.Shape instead of py_d2.D2Shape. The pull requests that were open on py-d2 are merged here, and most of its open issues are fixed. Issues and pull requests are welcome on this repository.

Development

You need uv.

git clone git@github.com:h0rv/d2-python.git && cd d2-python
uv sync --extra bin

uv run pytest
uv run ruff check
uv run ruff format
uv run ty check

To redraw the banner, run uv run python docs/banner.py.

License

d2-python is MIT licensed. The d2-bin package contains the unmodified D2 binary, which is licensed under the MPL-2.0 by Terrastruct.

About

A fully typed python interface for building .d2 graph files for use with the D2 engine.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages