D2COpenAIPlugin: Routing text to diagram backends
D2COpenAIPlugin is a FastAPI diagram service with a plugin manifest and an OpenAPI surface. Its implementation selects among PlantUML, Mermaid and Kroki paths based on the request’s diagram language.
Repository languagesPython 100%1
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| Python | 60,743 |
Overview
Why it exists
OpenAI ChatGPT plugin manifest and OpenAPI endpoint handler for text-to-diagram conversion.
Best fit
ChatGPT Plus GPT Store integration for software architects.
Getting started
These commands come from the repository documentation. They were not run during this review.
git clone https://github.com/antoinebou12/D2COpenAIPlugin.git
cd D2COpenAIPlugin
python -m venv .venv.\.venv\Scripts\Activate.ps1source .venv/bin/activatepip install -r requirements-dev.txt
python -m pytest
uvicorn app:app --host 127.0.0.1 --port 5003python app.pypip install plantumlapipip install git+https://github.com/antoinebou12/plantumlapiusage: plantuml.py [-h] [-o OUT] [-s SERVER] filename [filename ...]
Generate images from PlantUML defined files using PlantUML server
positional arguments:
filename file(s) to generate images from
optional arguments:
-h, --help show this help message and exit
-o OUT, --out OUT directory to put the files into
-s SERVER, --server SERVER
server to generate from; defaults to plantuml.com Tasks declared in manifests
Repository references
Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.
Prerequisites and first run
Requirements
README.md
- Python 3.10+ (CI uses 3.12)
- pip and a virtual environment (recommended) Optional:
- D2/main — small helper binary expected at ./D2/main for D2 encoding in D2/run_d2.py (only needed if you use the D2 code paths locally)
Quick start
README.md
Activate the venv (Windows PowerShell): Activate the venv (macOS / Linux): Install dependencies and run the API: Equivalent one-liner after activation:
Installation
plantuml/README.md
API and integration
API
README.md
| Field | Type | Required | Description |
|---|---|---|---|
| lang | string | yes | e.g. plantuml, mermaid, d2, or a Kroki type allowed by the server |
| type | string | yes | e.g. class, sequence, activity (used for validation / logging) |
| code | string | yes | Diagram source (max length enforced in app.py) |
| theme | string | no | PlantUML / Mermaid theming where applicable |
| Example (PlantUML) with curl (bash / Git Bash): | |||
| Example with PowerShell: |
POST /generate_diagram JSON body:
Operations and troubleshooting
Deployment (Vercel)
README.md
Development and contributions
Contributing / security
README.md
- Tests: python -m pytest (see .github/workflows/CI.yml)
- Security policy: SECURITY.md
Features and components 2
- Request model
- DiagramRequest contains lang, type, code and theme. Validators check the language and source length. /generate_diagram rejects missing fields before dispatching to a backend; the code then builds result and playground links.
- Backend adapters
- PlantUML uses its dedicated client, Mermaid builds an editor state, and D2 aliases are normalized to the Kroki d2 renderer. Other supported languages use the Kroki language registry. The adapters isolate differing URL and encoding conventions.
Architecture
The components and their connections remain available as text. The diagram adds an interactive view.
- Structured diagram request
- FastAPI model and route
- PlantUML adapter
- Mermaid state encoder
- Kroki adapter
- Result and playground links
Links verified in the repository.
Mermaid Interactive diagram (loads on open)
System overview of the components and connections verified in the repository.

flowchart LR
subgraph group_api["API surface"]
node_api["FastAPI endpoint<br/>[app.py]"]
node_request["Request validation<br/>[app.py]"]
node_response["Diagram response<br/>[app.py]"]
end
subgraph group_formats["Diagram formats"]
node_plantuml["PlantUML renderer<br/>[__init__.py]"]
node_mermaid["Mermaid state and links<br/>[mermaid.py]"]
node_d2encoder["D2 encoder<br/>[d2.py]"]
node_d2runner["D2 binary runner<br/>[run_d2.py]"]
node_kroki["Kroki client<br/>[kroki.py]"]
end
subgraph group_integration["Rendering services"]
node_plantservice["PlantUML server"]
node_mermaidink["Mermaid image service"]
node_mermaidlive["Mermaid Live Editor"]
node_krokiservice["Kroki service"]
end
subgraph group_assets["Plugin assets"]
node_pluginassets["Plugin metadata<br/>[ai-plugin.json]"]
node_openapi["OpenAPI specification<br/>[openapi.yaml]"]
node_privacy["Privacy policy<br/>[privacy.txt]"]
node_logo["Plugin logo"]
end
node_client(("Plugin client"))
node_client -->|"submits request"| node_api
node_api -->|"validates"| node_request
node_api -->|"dispatches PlantUML"| node_plantuml
node_plantuml -->|"requests rendering"| node_plantservice
node_api -->|"dispatches Mermaid"| node_mermaid
node_api -->|"dispatches D2 or allow-list"| node_kroki
node_kroki -->|"requests rendering"| node_krokiservice
node_mermaid -->|"creates image URL"| node_mermaidink
node_mermaid -->|"creates editor URL"| node_mermaidlive
node_api -->|"returns result"| node_response
node_pluginassets -->|"served by"| node_api
node_openapi -->|"describes API"| node_api
node_privacy -->|"served by"| node_api
node_logo -->|"served by"| node_api
node_d2runner -.->|"runs encoder binary"| node_d2encoder
class node_api,node_request,node_response,node_client toneBlue
class node_plantuml,node_mermaid,node_d2encoder,node_d2runner,node_kroki toneAmber
class node_plantservice,node_mermaidink,node_mermaidlive,node_krokiservice toneMint
class node_pluginassets,node_openapi,node_privacy,node_logo toneRoseA FastAPI diagram backend that validates requests, selects a PlantUML, Mermaid, D2 or Kroki path, and returns rendered content plus editor links. The service also publishes plugin, OpenAPI and privacy assets.
- Components
- 17
- Connections
- 15
- Links supported by code or README
- 13/15
Text version of the diagram
- Structured diagram request → FastAPI model and route
- FastAPI model and route → PlantUML adapter
- FastAPI model and route → Mermaid state encoder
- FastAPI model and route → Kroki adapter
- PlantUML adapter → Result and playground links
- Mermaid state encoder → Result and playground links
- Kroki adapter → Result and playground links
Follow one path through the code
Compare the PlantUML and D2 branches in app.py. They accept the same request model but use different rendering adapters. The type validator logs an invalid type rather than raising, so it is not equivalent to strict language validation.
Types and file structure
21 declared types, with 12 in the base-relationship overview.
Type diagram
classDiagram
direction TB
class te235e58dd5f7["DiagramRequest"] {
validate_lang()
validate_type()
validate_code()
}
class t4e73a5f77051["KrokiError"] {
}
class t7b9c286d0daa["KrokiConnectionError"] {
}
class t125669ef086e["KrokiHTTPError"] {
__init__()
}
class te53f5e9c5fc5["Kroki"] {
__init__()
get_url()
get_playground_url()
render_diagram()
}
class t8bdd6c0a1a17["Serde"] {
serialize()
deserialize()
}
class tb6d1e408057f["Base64Serde"] {
serialize()
deserialize()
}
class td8a94fefdf74["PakoSerde"] {
serialize()
deserialize()
pako_deflate()
pako_inflate()
}
class t3d10982f0435["Layout"] {
}
class tda3378b45b31["Theme"] {
}
class tc157562f2b44["PlantUMLError"] {
}
class t0b0db7ecf15c["PlantUMLConnectionError"] {
}
class bda110f9bf6d7["BaseModel"] {
<<unresolved_base>>
}
bda110f9bf6d7 <|-- te235e58dd5f7
class b03e969ca3e08["Exception"] {
<<unresolved_base>>
}
b03e969ca3e08 <|-- t4e73a5f77051
t4e73a5f77051 <|-- t7b9c286d0daa
t4e73a5f77051 <|-- t125669ef086e
t8bdd6c0a1a17 <|-- tb6d1e408057f
t8bdd6c0a1a17 <|-- td8a94fefdf74
class bb5991911b5e9["Enum"] {
<<unresolved_base>>
}
bb5991911b5e9 <|-- t3d10982f0435
bb5991911b5e9 <|-- tda3378b45b31
class b864a57f6df91["Exception"] {
<<unresolved_base>>
}
b864a57f6df91 <|-- tc157562f2b44
tc157562f2b44 <|-- t0b0db7ecf15c
Unresolved bases remain labelled; full signatures are not reconstructed.
Type index
DiagramRequest(class) ·app.py:47Methods in the overview:
validate_lang, validate_type, validate_code.Declared bases:
BaseModel.KrokiError(class) ·kroki/kroki.py:50Declared bases:
Exception.KrokiConnectionError(class) ·kroki/kroki.py:55Declared bases:
KrokiError.KrokiHTTPError(class) ·kroki/kroki.py:60Methods in the overview:
__init__.Declared bases:
KrokiError.Kroki(class) ·kroki/kroki.py:70Methods in the overview:
__init__, get_url, get_playground_url, render_diagram.Serde(class) ·mermaid/mermaid.py:32Methods in the overview:
serialize, deserialize.Base64Serde(class) ·mermaid/mermaid.py:39Methods in the overview:
serialize, deserialize.Declared bases:
Serde.PakoSerde(class) ·mermaid/mermaid.py:48Methods in the overview:
serialize, deserialize, pako_deflate, pako_inflate.Declared bases:
Serde.Layout(class) ·D2/d2.py:90Declared bases:
Enum.Theme(class) ·D2/d2.py:95Declared bases:
Enum.PlantUMLError(class) ·plantuml/__init__.py:23Declared bases:
Exception.PlantUMLConnectionError(class) ·plantuml/__init__.py:30Declared bases:
PlantUMLError.
Reference
17 / 17 eligible files read (35 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.
What the scan covers
Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.
Linguist statistics cover the whole repository and may include other languages.
File map
flowchart TD
root["D2COpenAIPlugin"]
f0["app.py"]
root --> f0
f1["kroki/kroki.py"]
root --> f1
f2["mermaid/mermaid.py"]
root --> f2
f3["README.md"]
root --> f3
f4["__init__.py"]
root --> f4
f5["package.json"]
root --> f5
f6["requirements.txt"]
root --> f6
f7["test_app.py"]
root --> f7
f8["D2/__init__.py"]
root --> f8
f9["D2/d2.py"]
root --> f9
f10["D2/run_d2.py"]
root --> f10
f11["kroki/__init__.py"]
root --> f11
f12["mermaid/__init__.py"]
root --> f12
f13["plantuml/README.md"]
root --> f13
f14["plantuml/__init__.py"]
root --> f14
f15["plantuml/themes/__init__.py"]
root --> f15
Files to read 3
References
- GitHubSource repository
- READMERepository documentation
- D2C OpenAI plugin — diagrams with PlantUML, Mermaid, and D2Blog article
- 25k uses for the diagram tool on the GPT StoreBlog article