A Python library that makes creating PlantUML diagrams intuitive via type hints
Project description
plantuml-compose
A Python library that makes creating PlantUML diagrams intuitive and type-safe.
https://github.com/jealouscloud/plantuml-compose
Why plantuml-compose?
PlantUML is powerful but its text syntax can be cryptic. What does A -[#red,dashed]-> B mean? What options are available for a state transition?
plantuml-compose solves this by providing:
- Discoverable APIs: Use your IDE's autocomplete to explore options
- Type safety: Catch errors before rendering, not after
- Pure factory functions: Compose diagrams declaratively with nesting
- Full PlantUML coverage: Every diagram type, every feature
Quick Start
from plantuml_compose import sequence_diagram, render
d = sequence_diagram(title="API Call")
p = d.participants
e = d.events
client = p.actor("Client")
server = p.participant("Server")
d.add(client, server)
d.phase("Request", [
e.message(client, server, "GET /users"),
e.reply(server, client, "200 OK"),
])
print(render(d))
The Pattern
Every diagram follows the same shape:
# 1. Create diagram — get namespace(s)
d = state_diagram(title="Lifecycle")
el = d.elements
t = d.transitions
# 2. Create elements via namespace factories
idle = el.state("Idle")
active = el.state("Active")
# 3. Register elements
d.add(idle, active)
# 4. Create and register connections
d.connect(
t.transitions(
(el.initial(), idle, "start"),
(idle, active, "go"),
(active, el.final(), "done"),
)
)
# 5. Render
print(render(d))
Namespaces organize the API — type d.elements. or d.transitions. and your IDE shows every available factory method.
Bulk helpers reduce repetition:
# Instead of individual calls:
t.transition(a, b, label="x"),
t.transition(b, c, label="y"),
t.transition(c, d, label="z"),
# Use the plural form:
t.transitions(
(a, b, "x"),
(b, c, "y"),
(c, d, "z"),
)
# Or fan-out from one source:
r.arrows_from(api,
(db, "queries"),
(cache, "reads"),
(queue, "publishes"),
)
Styling
Two levels of styling are available on every diagram type.
Inline styles on individual elements and connections:
# Element styling
el.state("Error", style={"background": "#FFCDD2", "line_color": "red"})
# Connection styling — string shorthand or dict
t.transition(a, b, style="dashed")
t.transition(a, b, style={"color": "red", "pattern": "dotted"})
# Arrow length (layout hint)
r.arrow(a, b, length=1) # short: ->
r.arrow(a, b, length=3) # long: --->
# Custom arrow heads
r.arrow(a, b, left_head="o", right_head=">>") # o-->>
Diagram-wide styling via diagram_style=:
d = class_diagram(
title="Model",
diagram_style={
"class_": {"background": "#E3F2FD", "round_corner": 10},
"arrow": {"line_color": "gray", "font_size": 10},
"note": {"background": "#FFF9C4"},
"stereotypes": {
"important": {"background": "pink", "font_style": "bold"},
},
},
)
Every element property is documented in ElementStyleDict — hover over it in your IDE to see all available keys (background, line_color, font_color, font_name, font_size, padding, margin, round_corner, shadowing, max_width, and more).
Supported Diagram Types
Behavioral
| Type | Use When | Guide |
|---|---|---|
| Sequence | Message flows between participants | API calls, protocols |
| State | Entity lifecycle tracking | Order status, workflows |
| Activity | Process flow with decisions and parallelism | Business processes, algorithms |
| Use Case | System boundaries and actor goals | Requirements, features |
| Timing | State changes over time | Hardware signals, protocol timing |
Structural
| Type | Use When | Guide |
|---|---|---|
| Class | Types, attributes, and relationships | Domain models, API types |
| Object | Specific instances and values | Test scenarios, snapshots |
| Component | System architecture | Services, modules, dependencies |
| Deployment | Software on infrastructure | Servers, containers, cloud |
| Network | Network topology | IP addressing, segments |
Hierarchical
| Type | Use When | Guide |
|---|---|---|
| Mind Map | Brainstorming and organizing ideas | Feature planning, concepts |
| WBS | Breaking down work | Project planning, tasks |
| Gantt | Scheduling with dependencies | Timelines, sprint planning |
Data & UI
| Type | Use When | Guide |
|---|---|---|
| JSON | Visualizing JSON data | API responses, config |
| YAML | Visualizing YAML data | Config files, specs |
| Salt | UI wireframes | Forms, layouts, menus |
Composition
| Feature | Guide |
|---|---|
| Sub-diagrams | Embed diagrams inside notes and messages |
Server URLs
from plantuml_compose import render, render_url
render_url(render(d)) # https://www.plantuml.com/plantuml/svg/...
render_url(render(d), format="png") # PNG format
render_url(render(d), server="http://my-server") # custom server
CLI: Markdown Processing
puml-md (also available as plantuml-compose md) processes markdown files, executing Python code blocks that import plantuml_compose and inserting rendered diagram images.
Given a markdown file containing:
```python
from plantuml_compose import state_diagram, render
d = state_diagram(title="Example")
d.add(d.elements.state("Active"))
print(render(d))
```
Running puml-md doc.md produces the same file with a diagram image appended after the code block:
```python
from plantuml_compose import state_diagram, render
d = state_diagram(title="Example")
d.add(d.elements.state("Active"))
print(render(d))
```

Re-running replaces existing diagram URLs rather than duplicating them.
puml-md doc.md # file → stdout
puml-md -i doc.md # in-place update
puml-md -id doc.md # in-place + wrap code in <details>
puml-md --validate doc.md # check diagrams against the server
cat doc.md | puml-md # stdin → stdout
| Flag | Description |
|---|---|
-i, --in-place |
Modify file in place |
-d, --details |
Wrap code blocks in collapsible <details><summary> |
--validate |
Check generated diagrams against the PlantUML server; exits non-zero on errors |
--server URL |
Custom PlantUML server (default: public server) |
--format FMT |
Output format: svg, png, txt (default: svg) |
Installation
pip install plantuml-compose
Requires Python 3.13+.
Development
# Install dependencies
uv sync
# Run tests
uv run pytest
# Validate output against PlantUML
plantuml --check-syntax output.puml
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file plantuml_compose-1.0.2.tar.gz.
File metadata
- Download URL: plantuml_compose-1.0.2.tar.gz
- Upload date:
- Size: 142.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.29 {"installer":{"name":"uv","version":"0.9.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"25.11","id":"xantusia","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89d50d67394121b077a5dc60f25afa534d0708b88983b58c668d2bf08794841c
|
|
| MD5 |
6a44a16945b6bc41048582962cbef2c3
|
|
| BLAKE2b-256 |
c38a9af1392ad8e9087ee66e83b8ae23ffe72f664b5bd4a1510ba3d79d2643ad
|
File details
Details for the file plantuml_compose-1.0.2-py3-none-any.whl.
File metadata
- Download URL: plantuml_compose-1.0.2-py3-none-any.whl
- Upload date:
- Size: 184.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.29 {"installer":{"name":"uv","version":"0.9.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"25.11","id":"xantusia","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6fc6578b81ffe10c6cab5acc2327b0d428e05090171ed3ec38b46123c4d1c46
|
|
| MD5 |
b3f5da4356418868a124a7e11bc59094
|
|
| BLAKE2b-256 |
876ec1466667ba3ef97b9b8961d4cda533c5a2491a852d1ef315baaf03e3228d
|