Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,25 @@ An unofficial, fully typed python interface for building [.d2](https://github.co
## Installation

```bash
pip install py-d2
pip install d2-python
```

## Usage

```python
from py_d2 import D2Diagram, D2Shape, D2Connection, D2Style
import d2

shapes = [
D2Shape(name="shape_name1", style=D2Style(fill="red")),
D2Shape(name="shape_name2", style=D2Style(fill="blue"))]
d2.Shape(name="shape_name1", style=d2.Style(fill="red")),
d2.Shape(name="shape_name2", style=d2.Style(fill="blue"))]
connections = [
D2Connection(shape_1="shape_name1", shape_2="shape_name2")
d2.Connection(shape_1="shape_name1", shape_2="shape_name2")
]

diagram = D2Diagram(shapes=shapes, connections=connections)
diagram = d2.Diagram(shapes=shapes, connections=connections)

with open("graph.d2", "w", encoding="utf-8") as f:
f.write(str(diagram))

```

produces the following graph.d2 file:
Expand Down Expand Up @@ -104,7 +103,7 @@ following the steps below to setup the project:

```bash
# Clone the repository
git clone git@github.com:MrBlenny/py-d2.git && cd py-d2
git clone git@github.com:h0rv/d2-python.git && cd d2-python

# Install all dependencies
uv sync --all-extras --dev
Expand Down
10 changes: 5 additions & 5 deletions examples/simple_sql_schema.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import os
import subprocess

from py_d2.diagram import D2Diagram
from py_d2.sql_table import SQLConstraint
from py_d2.sql_table import SQLTable
from py_d2.sql_table import create_foreign_key_connection
from d2.diagram import Diagram
from d2.sql_table import SQLConstraint
from d2.sql_table import SQLTable
from d2.sql_table import create_foreign_key_connection


FILE_NAME = "simple_sql_schema"

# Create a new diagram
diagram = D2Diagram()
diagram = Diagram()

# Create Users table
users = SQLTable("users")
Expand Down
18 changes: 10 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "py-d2"
version = "1.1.0"
name = "d2-python"
version = "1.0.0"
description = "An unofficial, fully typed python interface for building .d2 graph files in python."
authors = [
{name = "David Revay", email = "daverevay@gmail.com"},
Expand All @@ -10,6 +10,7 @@ license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.8"
keywords = [
"d2-python",
"d2",
"py-d2",
"d2-lang",
Expand All @@ -32,12 +33,12 @@ classifiers = [
]

[project.urls]
Repository = "https://github.com/h0rv/py-d2"
Documentation = "https://github.com/h0rv/py-d2/blob/main/README.md"
"Bug Tracker" = "https://github.com/h0rv/py-d2/issues"
Repository = "https://github.com/h0rv/d2-python"
Documentation = "https://github.com/h0rv/d2-python/blob/main/README.md"
"Bug Tracker" = "https://github.com/h0rv/d2-python/issues"

[project.scripts]
example = "py_d2.main:example"
example = "d2.main:example"

[project.optional-dependencies]
dev = [
Expand All @@ -56,7 +57,8 @@ coverage = [
[tool.uv]
package = true

[tool.uv.sources]
[tool.uv.build-backend]
module-name = "d2"

[build-system]
requires = ["uv_build>=0.7.19,<0.8.0"]
Expand Down Expand Up @@ -105,4 +107,4 @@ line-ending = "auto"
force-single-line = true
force-sort-within-sections = true
lines-after-imports = 2
known-first-party = ["py_d2"]
known-first-party = ["d2"]
20 changes: 20 additions & 0 deletions src/d2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from .connection import Connection
from .connection import Direction
from .diagram import Diagram
from .diagram import Layer
from .shape import Shape
from .shape import ShapeType
from .shape import Text
from .style import Style


__all__ = [
"Direction",
"Connection",
"Diagram",
"Shape",
"ShapeType",
"Text",
"Style",
"Layer",
]
2 changes: 1 addition & 1 deletion src/py_d2/connection.py → src/d2/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Direction(Enum):
NONE = "--"


class D2Connection:
class Connection:
def __init__(self, shape_1: str, shape_2: str, label: Optional[str] = None, direction: Direction = Direction.TO):
self.shape_1 = shape_1
self.shape_2 = shape_2
Expand Down
24 changes: 12 additions & 12 deletions src/py_d2/diagram.py → src/d2/diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
from typing import List
from typing import Optional

from py_d2.connection import D2Connection
from py_d2.helpers import indent
from py_d2.helpers import indent_lines
from py_d2.shape import D2Shape
from d2.connection import Connection
from d2.helpers import indent
from d2.helpers import indent_lines
from d2.shape import Shape


class Layer:
def __init__(
self,
name: str,
diagram: Optional[D2Diagram] = None,
diagram: Optional[Diagram] = None,
):
self.name = name
self.diagram = diagram or D2Diagram()
self.diagram = diagram or Diagram()

def set_diagram(self, diagram: D2Diagram):
def set_diagram(self, diagram: Diagram):
self.diagram = diagram

def lines(self, depth=1) -> List[str]:
Expand All @@ -44,21 +44,21 @@ def __repr__(self) -> str:
return "\n".join(lines)


class D2Diagram:
class Diagram:
def __init__(
self,
shapes: Optional[List[D2Shape]] = None,
connections: Optional[List[D2Connection]] = None,
shapes: Optional[List[Shape]] = None,
connections: Optional[List[Connection]] = None,
layers: Optional[List[Layer]] = None,
):
self.shapes = shapes or []
self.connections = connections or []
self.layers = layers or []

def add_shape(self, shape: D2Shape):
def add_shape(self, shape: Shape):
self.shapes.append(shape)

def add_connection(self, connection: D2Connection):
def add_connection(self, connection: Connection):
self.connections.append(connection)

def add_layer(self, layer: Layer):
Expand Down
File renamed without changes.
24 changes: 24 additions & 0 deletions src/d2/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from d2.connection import Connection
from d2.diagram import Diagram
from d2.shape import Shape
from d2.style import Style


def example():
print("Contructing a simple graph...")
shapes = [
Shape(name="shape_name1", style=Style(fill="red")),
Shape(name="shape_name2", style=Style(fill="blue")),
]
connections = [Connection(shape_1="shape_name1", shape_2="shape_name2")]

diagram = Diagram(shapes=shapes, connections=connections)

print("Writing graph to file...")
with open("graph.d2", "w", encoding="utf-8") as f:
f.write(str(diagram))
print("Done! (graph.d2)")


if __name__ == "__main__":
example()
File renamed without changes.
30 changes: 15 additions & 15 deletions src/py_d2/shape.py → src/d2/shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from typing import List
from typing import Optional

from py_d2.connection import D2Connection
from py_d2.helpers import add_label_and_properties
from py_d2.helpers import flatten
from py_d2.helpers import indent_lines
from py_d2.style import D2Style
from d2.connection import Connection
from d2.helpers import add_label_and_properties
from d2.helpers import flatten
from d2.helpers import indent_lines
from d2.style import Style


class Shape(Enum):
class ShapeType(Enum):
rectangle = "rectangle"
square = "square"
page = "page"
Expand All @@ -37,7 +37,7 @@ class Shape(Enum):
sequence_diagram = "sequence_diagram"


class D2Text:
class Text:
def __init__(
self,
# The actual text body (multiline is fine)
Expand All @@ -59,27 +59,27 @@ def __repr__(self) -> str:
return "\n".join(self.lines())


class D2Shape:
class Shape:
def __init__(
self,
name: str,
# The label of this shape
label: Optional[str] = None,
# The actual 2D shape of this shape
shape: Optional[Shape] = None,
shape: Optional[ShapeType] = None,
# A list of child shapes (when this shape is a container)
shapes: Optional[List[D2Shape]] = None,
shapes: Optional[List[Shape]] = None,
# The style of this shape
style: Optional[D2Style] = None,
style: Optional[Style] = None,
# An icon for this shape
icon: Optional[str] = None,
# Connections for the child shapes (NOT the connections for this shape)
connections: Optional[List[D2Connection]] = None,
connections: Optional[List[Connection]] = None,
# A shape this is near
near: Optional[str] = None,
# A link for a shape (when clicked)
link: Optional[str] = None,
**kwargs: D2Text,
**kwargs: Text,
):
self.name = name
self.label = label
Expand All @@ -92,10 +92,10 @@ def __init__(
self.link = link
self.kwargs = kwargs

def add_shape(self, shape: D2Shape):
def add_shape(self, shape: Shape):
self.shapes.append(shape)

def add_connection(self, connection: D2Connection):
def add_connection(self, connection: Connection):
self.connections.append(connection)

def lines(self) -> List[str]:
Expand Down
18 changes: 9 additions & 9 deletions src/py_d2/sql_table.py → src/d2/sql_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from typing import Optional
from typing import Union

from py_d2.connection import D2Connection
from py_d2.connection import Direction
from py_d2.shape import D2Shape
from py_d2.shape import Shape
from d2.connection import Connection
from d2.connection import Direction
from d2.shape import Shape
from d2.shape import ShapeType


class SQLConstraint(Enum):
Expand Down Expand Up @@ -52,7 +52,7 @@ def to_d2_format(self) -> str:
return f"{self.name}: {self.data_type} {{constraint: {constraint_part}}}"


class SQLTable(D2Shape):
class SQLTable(Shape):
def __init__(
self,
name: str,
Expand All @@ -66,7 +66,7 @@ def __init__(
super().__init__(
name=name,
label=label,
shape=Shape.sql_table,
shape=ShapeType.sql_table,
style=style,
icon=icon,
near=near,
Expand Down Expand Up @@ -135,7 +135,7 @@ def lines(self) -> List[str]:
properties.extend(connection_lines)

# Create the final lines
from py_d2.helpers import add_label_and_properties
from d2.helpers import add_label_and_properties

lines = add_label_and_properties(self.name, self.label, properties)

Expand All @@ -148,8 +148,8 @@ def create_foreign_key_connection(
target_table: str,
target_field: str,
label: Optional[str] = None,
) -> D2Connection:
) -> Connection:
"""Create a foreign key connection between two tables."""
source = f"{source_table}.{source_field}"
target = f"{target_table}.{target_field}"
return D2Connection(source, target, label, Direction.TO)
return Connection(source, target, label, Direction.TO)
4 changes: 2 additions & 2 deletions src/py_d2/style.py → src/d2/style.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from typing import List
from typing import Optional

from py_d2.helpers import add_label_and_properties
from d2.helpers import add_label_and_properties


def stringify_bool(val: bool) -> str:
return "true" if val else "false"


class D2Style:
class Style:
def __init__(
self,
stroke: Optional[str] = None,
Expand Down
20 changes: 0 additions & 20 deletions src/py_d2/__init__.py

This file was deleted.

Loading