blockdiag/seqdiag to Mermaid Diagram Migration
- Author:
Matthew Watkins (Linux Foundation Release Engineering)
- References:
Overview
All ONAP documentation repositories that contained live .. blockdiag::
or .. seqdiag:: diagram directives have been identified, and their
diagrams converted to .. mermaid:: syntax. 9 diagrams across
5 repositories were migrated.
This migration removed the dependency on the abandoned
sphinxcontrib-blockdiag and sphinxcontrib-seqdiag Python packages,
which are incompatible with both Pillow >= 10 and Python >= 3.12.
With this work complete, all ONAP documentation builds cleanly on
Python 3.13 without the Pillow<10 workaround that was previously
required.
The approach described here is applicable to any Sphinx-based documentation project that still depends on blockdiag or seqdiag and needs to move to a modern, actively maintained diagramming solution.
Background
Why migrate?
The sphinxcontrib-blockdiag and sphinxcontrib-seqdiag Sphinx
extensions have been abandoned by their upstream maintainers. They suffer
from two critical compatibility failures:
Python 3.12+ incompatibility —
blockdiag 3.0.0usesast.NameConstant, which was removed in Python 3.12. Any import of the module crashes immediately.Pillow 10+ incompatibility —
blockdiag 3.0.0callsImageDraw.textsize(), which was deprecated in Pillow 9.2.0 and removed in Pillow 10.0. Documentation builds that pin a modern Pillow version will fail with:AttributeError: 'ImageDraw' object has no attribute 'textsize'
Why Mermaid?
sphinxcontrib-mermaid was selected over alternatives for the following
reasons:
Criterion |
sphinxcontrib-mermaid |
sphinxcontrib-plantuml |
sphinx.ext.graphviz |
blockdiag |
seqdiag |
|---|---|---|---|---|---|
Actively maintained |
✅ Yes |
✅ Yes |
✅ Built-in |
❌ Abandoned |
❌ Abandoned |
Python 3.12+ compatible |
✅ Yes |
✅ Yes |
✅ Yes |
❌ No |
❌ No |
Pillow 10+ compatible |
✅ N/A (JS-rendered) |
✅ N/A (Java) |
✅ N/A (native) |
❌ No |
❌ No |
No server-side binary |
✅ CDN JS |
❌ Requires Java + PlantUML jar |
❌ Requires |
❌ Requires Pillow + fonts |
❌ Requires Pillow + fonts |
Block diagrams |
✅ |
✅ Yes |
✅ |
✅ Yes |
❌ No |
Sequence diagrams |
✅ |
✅ Yes |
❌ No |
❌ No |
✅ Yes |
ReadTheDocs compatible |
✅ Yes |
⚠️ Needs Java in build |
⚠️ Needs graphviz in build |
❌ Broken |
❌ Broken |
GitHub rendering |
✅ Native ( |
❌ No |
❌ No |
❌ No |
❌ No |
Migration scope
The table below summarises every repository that required a content or configuration change as part of this migration.
Repository |
Diagram type |
Count |
Description |
|---|---|---|---|
|
blockdiag |
1 |
Bus Controller API connections to MR, DR, AAF |
|
blockdiag |
1 |
DR-PROV, DR-NODE, MariaDB container connectivity |
|
graphviz |
2 |
Already used graphviz; config-only cleanup required |
|
N/A (config only) |
0 |
blockdiag/seqdiag loaded in |
|
seqdiag |
4 |
VES v7.1 and v7.2 call-flow diagrams |
Metric |
Count |
|---|---|
Repositories requiring content migration |
3 |
Repositories requiring config-only cleanup |
2 |
|
2 |
|
4 |
|
2 |
Total diagrams migrated or verified |
9 |
Before / after diagrams
This section shows the original blockdiag/seqdiag rendering alongside the replacement Mermaid diagram for each migration performed.
dmaap/buscontroller — Bus Controller Architecture
Before (blockdiag):
After (Mermaid):
graph TD
DBC_CLIENT["DBC_CLIENT"] --> DBC_API["DBC_API"]
DBC_API --> MR["MR"]
DBC_API --> DR["DR"]
DBC_API --> AAF["AAF"]
subgraph sg_bcc ["Bus Controller Container"]
DBC_API
end
subgraph sg_mr ["MR"]
MR
end
subgraph sg_dr ["DR"]
DR
end
subgraph sg_aaf ["AAF"]
AAF
end
classDef blueStyle fill:#33f,stroke:#333,color:#fff
classDef yellowStyle fill:#ff0,stroke:#333,color:#000
classDef orangeStyle fill:#f90,stroke:#333,color:#000
classDef greenStyle fill:#0c0,stroke:#333,color:#000
class DBC_API blueStyle
class MR yellowStyle
class DR orangeStyle
class AAF greenStyle
dmaap/datarouter — Data Router Delivery
Before (blockdiag):
After (Mermaid):
graph TD
MARIADB["MARIADB"] --> DR_PROV["DR-PROV"]
DR_PROV --> DR_NODE["DR-NODE"]
subgraph "dr-prov Container"
DR_PROV
end
subgraph "dr-node Container"
DR_NODE
end
subgraph "MariaDb Container"
MARIADB
end
classDef blueStyle fill:#33f,stroke:#333,color:#fff
classDef yellowStyle fill:#ff0,stroke:#333,color:#000
classDef orangeStyle fill:#f90,stroke:#333,color:#000
class DR_PROV blueStyle
class DR_NODE yellowStyle
class MARIADB orangeStyle
vnfrqts/requirements — VES publishAnyEvent Call Flow
This pattern is identical in VES 7.1 (ves7_1spec.rst) and VES 7.2
(ves_event_listener_7_2.rst).
Before (seqdiag):
After (Mermaid):
sequenceDiagram
participant client
participant listener
client->>listener: POST /eventlistener/v7
listener-->>client: HTTP 202 Accepted
Note right of listener: sync response
rect rgb(255, 230, 230)
Note over client, listener: Error Scenario
client->>listener: POST /eventlistener/v7
listener-->>client: HTTP 4XX/5XX
Note right of listener: sync response
end
publishAnyEvent Call Flow
vnfrqts/requirements — VES publishEventBatch Call Flow
This pattern is identical in VES 7.1 (ves7_1spec.rst) and VES 7.2
(ves_event_listener_7_2.rst).
Before (seqdiag):
After (Mermaid):
sequenceDiagram
participant client
participant listener
rect rgb(232, 245, 233)
Note over client, listener: Success Scenario
client->>listener: POST /eventlistener/v7/eventBatch
listener-->>client: HTTP 202 Accepted
Note right of listener: sync response
end
rect rgb(255, 235, 238)
Note over client, listener: Error Scenario
client->>listener: POST /eventlistener/v7/eventBatch
listener-->>client: HTTP 4XX/5XX
Note right of listener: sync response
end
publishEventBatch Call Flow
Mermaid syntax pitfalls
Several issues were encountered during the conversion that are worth noting for anyone performing a similar migration:
Node identifiers with hyphens
Mermaid interprets bare hyphens in node identifiers as minus operators.
A node written as DR-PROV will cause a parse error. Use an explicit
label to work around this:
DR_PROV["DR-PROV"]
The internal identifier uses underscores, while the displayed label preserves the original hyphenated name.
Subgraph title / node ID collisions
When a subgraph title matches a node ID, Mermaid treats the title as the subgraph’s internal identifier and attempts to make the node a child of itself, producing a cycle error such as:
Error: Setting AAF as parent of AAF would create a cycle
Assign an explicit subgraph ID that differs from any node ID:
subgraph sg_aaf ["AAF"]
AAF
end
Reserved classDef names
Mermaid reserves certain colour keywords. Defining a class called
blue, green, or orange can conflict with the parser in some
Mermaid versions. Use descriptive suffixed names instead:
classDef blueStyle fill:#33f,stroke:#333,color:#fff
class MY_NODE blueStyle
Applying the migration to other projects
The steps below summarise the process used for ONAP and can be followed by any Sphinx-based documentation project that depends on blockdiag or seqdiag.
Audit repositories — search for live
.. blockdiag::and.. seqdiag::directives across all documentation sources.Update
docs/conf.py— removesphinxcontrib.blockdiagandsphinxcontrib.seqdiagfrom theextensionslist; addsphinxcontrib.mermaid.Update
requirements-docs.txt— remove the blockdiag/seqdiag packages and addsphinxcontrib-mermaid.Remove Pillow workarounds — delete any
Pillow<10pins fromtox.inior constraint files that were added solely to keep blockdiag functioning.Convert each diagram — rewrite every
.. blockdiag::directive as a.. mermaid:: graphand every.. seqdiag::directive as a.. mermaid:: sequenceDiagram. See Migrating from blockdiag/seqdiag to Mermaid for a full syntax-mapping guide with worked examples.Verify the build — run
tox -e docswith the target Python version (3.13 or later) and confirm thatsphinx-build -W(warnings-as-errors) passes and all diagrams render correctly.Clean up config-only repositories — any repository that loads the blockdiag/seqdiag extensions without using any directives needs only the configuration changes from steps 2–4.