Python Diagrams and Graphviz

Published: Jul 18, 2024 by Isaac Johnson

Recently, a colleague of mine pointed out “Diagrams as Code” from diagrams.mingrammer.com. The examples on the main page looked a lot nicer than what I usually kick out with MermaidJS so I figure we should give it a try.

Diagrams with Graphviz, or is it Graphviz in Diagrams. Either way, they seem similar though “Diagrams”, the library for Python that depends on Graphviz clearly can do more - like a superset.

Let’s dig in!

setup

We can start with the installation guide.

What is cool is that this is based on Graphviz which we looked at briefly when exploring HedgeDoc in June.

Let’s start with some python

builder@LuiGi:~/Workspaces$ mkdir diagrams
builder@LuiGi:~/Workspaces$ cd diagrams/
builder@LuiGi:~/Workspaces/diagrams$ pip install diagrams
Defaulting to user installation because normal site-packages is not writeable
Collecting diagrams
  Downloading diagrams-0.23.4-py3-none-any.whl (24.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 24.6/24.6 MB 2.0 MB/s eta 0:00:00
Collecting graphviz<0.21.0,>=0.13.2
  Downloading graphviz-0.20.3-py3-none-any.whl (47 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.1/47.1 KB 1.0 MB/s eta 0:00:00
Requirement already satisfied: jinja2<4.0,>=2.10 in /home/builder/.local/lib/python3.10/site-packages (from diagrams) (3.1.3)
Collecting typed-ast<2.0.0,>=1.5.4
  Downloading typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (824 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 824.7/824.7 KB 3.1 MB/s eta 0:00:00
Requirement already satisfied: MarkupSafe>=2.0 in /home/builder/.local/lib/python3.10/site-packages (from jinja2<4.0,>=2.10->diagrams) (2.1.5)
Installing collected packages: typed-ast, graphviz, diagrams
Successfully installed diagrams-0.23.4 graphviz-0.20.3 typed-ast-1.5.5

I first tried using a pip install

$ pip install diagrams
Defaulting to user installation because normal site-packages is not writeable
Collecting diagrams
  Downloading diagrams-0.23.4-py3-none-any.whl (24.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 24.6/24.6 MB 2.0 MB/s eta 0:00:00
Collecting graphviz<0.21.0,>=0.13.2
  Downloading graphviz-0.20.3-py3-none-any.whl (47 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.1/47.1 KB 1.0 MB/s eta 0:00:00
Requirement already satisfied: jinja2<4.0,>=2.10 in /home/builder/.local/lib/python3.10/site-packages (from diagrams) (3.1.3)
Collecting typed-ast<2.0.0,>=1.5.4
  Downloading typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (824 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 824.7/824.7 KB 3.1 MB/s eta 0:00:00
Requirement already satisfied: MarkupSafe>=2.0 in /home/builder/.local/lib/python3.10/site-packages (from jinja2<4.0,>=2.10->diagrams) (2.1.5)
Installing collected packages: typed-ast, graphviz, diagrams
Successfully installed diagrams-0.23.4 graphviz-0.20.3 typed-ast-1.5.5

Then some sample code

builder@LuiGi:~/Workspaces/diagrams$ cat diagram-sample.py
# diagram.py
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Web Service", show=False):
        ELB("ELB") >> EC2("Web") >> RDS("Users DB")

But Python didn’t find the library

builder@LuiGi:~/Workspaces/diagrams$ python3 diagram-sample.py
Traceback (most recent call last):
  File "/home/builder/Workspaces/diagrams/diagram-sample.py", line 2, in <module>
    from diagrams import Diagram
ModuleNotFoundError: No module named 'diagrams'

My pip3 suggested to use homebrew to install, so I tried that

builder@LuiGi:~/Workspaces/diagrams$ brew install graphviz
==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
asak           cotila         envelope       kaskade        llgo           otree          qrtool         testscript
awsdac         cyme           frizbee        kubevpn        mako           porter         ryelang        topfew
chkbit         dnsgen         ftnchek        lando-cli      nerdfetch      pug            soapyhackrf    wcurl
cortexso       egctl          h26forge       litmusctl      openbao        pulsarctl      subliminal
==> New Casks
airdash                                 font-big-shoulders-stencil-display-sc   lazycat
ball                                    font-big-shoulders-stencil-text-sc      monokle
blip                                    font-big-shoulders-text-sc              navicat-premium-lite
charmstone                              font-dotum                              notchnook
clash-verge-rev                         font-dotumche                           orka-desktop
crashplan                               font-fragment-mono-sc                   pia
ea                                      font-gulim                              plugdata@nightly
font-afacad-flux                        font-gulimche                           positron
font-alumni-sans-sc                     font-gungsuh                            productive
font-batang                             font-gungsuhche                         replit
font-batangche                          font-maname                             retroarch-metal@nightly
font-big-shoulders-display-sc           font-sixtyfour-convergence              wd-security
font-big-shoulders-inline-display-sc    inkdown                                 yaak
font-big-shoulders-inline-text-sc       k8studio

You have 3 outdated formulae installed.

==> Downloading https://ghcr.io/v2/homebrew/core/graphviz/manifests/12.0.0
################################################################################################################# 100.0%
==> Fetching dependencies for graphviz: libpng, freetype, util-linux, fontconfig, jpeg-turbo, brotli, giflib, highway, imath, lz4, zstd, libtiff, little-cms2, openexr, webp, ca-certificates, krb5, jpeg-xl, libvmaf, aom, libavif, gd, pcre2, dbus, glib, jasper, icu4c, libxml2, netpbm, gts, xorgproto, libxau, libxdmcp, libxcb, libx11, libxext, libxrender, lzo, pixman, cairo, shared-mime-info, gdk-pixbuf, fribidi, graphite2, harfbuzz, pango, librsvg, m4 and libtool
==> Downloading https://ghcr.io/v2/homebrew/core/libpng/manifests/1.6.43
################################################################################################################# 100.0%
==> Fetching libpng
==> Downloading https://ghcr.io/v2/homebrew/core/libpng/blobs/sha256:af870ecc2a8824919dd700525424c92bad4567fc0efdc462688
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/freetype/manifests/2.13.2-1
################################################################################################################# 100.0%
==> Fetching freetype
==> Downloading https://ghcr.io/v2/homebrew/core/freetype/blobs/sha256:7f4f7449ac197844846126b6e002f7faf10b5da5b333f203e
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/util-linux/manifests/2.40.2
################################################################################################################# 100.0%
==> Fetching util-linux
==> Downloading https://ghcr.io/v2/homebrew/core/util-linux/blobs/sha256:2ab17c3336042dc8e51d1564ffec4320f7b29e2e7be5619
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/fontconfig/manifests/2.15.0
################################################################################################################# 100.0%
==> Fetching fontconfig
==> Downloading https://ghcr.io/v2/homebrew/core/fontconfig/blobs/sha256:1cb0f103706d1199c9917ec6908d9f027eb9688faee40a4
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-turbo/manifests/3.0.3
################################################################################################################# 100.0%
==> Fetching jpeg-turbo
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-turbo/blobs/sha256:5fa10c311ff3da224a81663de1fedd246878a5e435edca0
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/brotli/manifests/1.1.0-1
################################################################################################################# 100.0%
==> Fetching brotli
==> Downloading https://ghcr.io/v2/homebrew/core/brotli/blobs/sha256:5a2e1cc12312a092b38e79952fd2232f564f2c64cda0f69e97a
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/giflib/manifests/5.2.2
################################################################################################################# 100.0%
==> Fetching giflib
==> Downloading https://ghcr.io/v2/homebrew/core/giflib/blobs/sha256:db5d2754722a81e5a842a66236aeebe889ebae26b08329dbd50
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/highway/manifests/1.2.0
################################################################################################################# 100.0%
==> Fetching highway
==> Downloading https://ghcr.io/v2/homebrew/core/highway/blobs/sha256:7dfee6723c0915e37b9253347c24bca7a2e37f0823a2e28834
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/imath/manifests/3.1.11
################################################################################################################# 100.0%
==> Fetching imath
==> Downloading https://ghcr.io/v2/homebrew/core/imath/blobs/sha256:c405f3c1093df42aa82c2e2da39ed9b83ce0f7569864ec56560e
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/lz4/manifests/1.9.4
################################################################################################################# 100.0%
==> Fetching lz4
==> Downloading https://ghcr.io/v2/homebrew/core/lz4/blobs/sha256:1757fefc3840e11c4822e4c2a95aa62aca44a4eaccce6f5c414ea5
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/zstd/manifests/1.5.6
################################################################################################################# 100.0%
==> Fetching zstd
==> Downloading https://ghcr.io/v2/homebrew/core/zstd/blobs/sha256:0e6ddbd4c969bb84261f12b759fb78a828d6f734c9e515793c6ac
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libtiff/manifests/4.6.0
################################################################################################################# 100.0%
==> Fetching libtiff
==> Downloading https://ghcr.io/v2/homebrew/core/libtiff/blobs/sha256:9a6e0bb56c39b72a33b0a5629dc3fd49e4f1391513bcf7d04a
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/little-cms2/manifests/2.16
################################################################################################################# 100.0%
==> Fetching little-cms2
==> Downloading https://ghcr.io/v2/homebrew/core/little-cms2/blobs/sha256:79268ac2afeaaa7bce8af516f329f808443c3bbad64e70
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/openexr/manifests/3.2.4
################################################################################################################# 100.0%
==> Fetching openexr
==> Downloading https://ghcr.io/v2/homebrew/core/openexr/blobs/sha256:d7c839fd2991b3cc8a66a5e5fa6aa4d86e3d9621280d56b242
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/webp/manifests/1.4.0
################################################################################################################# 100.0%
==> Fetching webp
==> Downloading https://ghcr.io/v2/homebrew/core/webp/blobs/sha256:689bc7cdc7b5468f779265c66b4140ad911ea6bac85dc1df33bb6
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/ca-certificates/manifests/2024-07-02
################################################################################################################# 100.0%
==> Fetching ca-certificates
==> Downloading https://ghcr.io/v2/homebrew/core/ca-certificates/blobs/sha256:73eb1a6bf9a5e12ee3f1acd295a4aaa28f08a9125a
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/krb5/manifests/1.21.3
################################################################################################################# 100.0%
==> Fetching krb5
==> Downloading https://ghcr.io/v2/homebrew/core/krb5/blobs/sha256:f5b4cafedb315e92a31a0a5d87e33f7826952bcc5c093ba65817c
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-xl/manifests/0.10.3
################################################################################################################# 100.0%
==> Fetching jpeg-xl
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-xl/blobs/sha256:64b61d8a8d21bed6842b83b3e2810fe12ad1d77bdad9781850
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libvmaf/manifests/3.0.0
################################################################################################################# 100.0%
==> Fetching libvmaf
==> Downloading https://ghcr.io/v2/homebrew/core/libvmaf/blobs/sha256:5cb81b38b8c402fc0c12a8a639a7208406958d27a1f8a513c7
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/aom/manifests/3.9.1
################################################################################################################# 100.0%
==> Fetching aom
==> Downloading https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:d018fbe0e71201de17504c3a5ed73f3499dfd36b1b07a09173e826
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libavif/manifests/1.0.4
################################################################################################################# 100.0%
==> Fetching libavif
==> Downloading https://ghcr.io/v2/homebrew/core/libavif/blobs/sha256:88c480ade965017a0f73774b2517df7579fd06dc9495db9d08
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/gd/manifests/2.3.3_6
################################################################################################################# 100.0%
==> Fetching gd
==> Downloading https://ghcr.io/v2/homebrew/core/gd/blobs/sha256:da124ea2c614748107f9683ed08afa140d98a5d429332137f4f6ce1
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/pcre2/manifests/10.44
################################################################################################################# 100.0%
==> Fetching pcre2
==> Downloading https://ghcr.io/v2/homebrew/core/pcre2/blobs/sha256:cbddfbb9921fa2894640db7f0395ea8a79ce5209ebe5ae670076
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/dbus/manifests/1.14.10
################################################################################################################# 100.0%
==> Fetching dbus
==> Downloading https://ghcr.io/v2/homebrew/core/dbus/blobs/sha256:9037402e48fc19b05f8b621e0e32efa3b4214513f0b4737894ef3
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/glib/manifests/2.80.4
################################################################################################################# 100.0%
==> Fetching glib
==> Downloading https://ghcr.io/v2/homebrew/core/glib/blobs/sha256:75af431b3cf94313eb31f3e6433ca3e39b42d1cfe538bc7bc92c5
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/jasper/manifests/4.2.4
################################################################################################################# 100.0%
==> Fetching jasper
==> Downloading https://ghcr.io/v2/homebrew/core/jasper/blobs/sha256:e8a209bbc3755e5ae06cf4c7ab8040e079b0202635555ea4c75
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/icu4c/manifests/74.2
################################################################################################################# 100.0%
==> Fetching icu4c
==> Downloading https://ghcr.io/v2/homebrew/core/icu4c/blobs/sha256:2b881638861905a1a730cdd618966dfcb548685314d86addd1ad
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxml2/manifests/2.12.8
################################################################################################################# 100.0%
==> Fetching libxml2
==> Downloading https://ghcr.io/v2/homebrew/core/libxml2/blobs/sha256:fb5cd905b75c9bed36f3deb284e6a6f4c3338f78368cff9f52
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/netpbm/manifests/11.02.09
################################################################################################################# 100.0%
==> Fetching netpbm
==> Downloading https://ghcr.io/v2/homebrew/core/netpbm/blobs/sha256:0d770e45c84acf2e16e7d16ed8144e35960304c18a63235826a
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/gts/manifests/0.7.6_3
################################################################################################################# 100.0%
==> Fetching gts
==> Downloading https://ghcr.io/v2/homebrew/core/gts/blobs/sha256:4c6bb3e3859bee6f8b113a08d7d158a19ef46ec307073fac12c90c
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/xorgproto/manifests/2024.1
################################################################################################################# 100.0%
==> Fetching xorgproto
==> Downloading https://ghcr.io/v2/homebrew/core/xorgproto/blobs/sha256:fc1ef8db0fe244a7a47541fe8494131a281814a4110d3af4
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxau/manifests/1.0.11
################################################################################################################# 100.0%
==> Fetching libxau
==> Downloading https://ghcr.io/v2/homebrew/core/libxau/blobs/sha256:ba968fc488e6fa7d6d1f734ff79b85f0b4ed2ffa8dd7d19b0e6
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxdmcp/manifests/1.1.5
################################################################################################################# 100.0%
==> Fetching libxdmcp
==> Downloading https://ghcr.io/v2/homebrew/core/libxdmcp/blobs/sha256:d8b9dc2969e85e26c6d426d8865244e1416d73f7f408c9f54
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxcb/manifests/1.17.0
################################################################################################################# 100.0%
==> Fetching libxcb
==> Downloading https://ghcr.io/v2/homebrew/core/libxcb/blobs/sha256:c89a99c1bd6af9c2ee85f4c7bacd07906bb16e6ab515cd5d347
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/manifests/1.8.9
################################################################################################################# 100.0%
==> Fetching libx11
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/blobs/sha256:51b67b10bfcc472bdad4beeff32730e273f2f09caccf59d9fd7
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxext/manifests/1.3.6
################################################################################################################# 100.0%
==> Fetching libxext
==> Downloading https://ghcr.io/v2/homebrew/core/libxext/blobs/sha256:c62be32e864f64fc9ed3392a2f6eae085350c5b929b52306ac
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libxrender/manifests/0.9.11
################################################################################################################# 100.0%
==> Fetching libxrender
==> Downloading https://ghcr.io/v2/homebrew/core/libxrender/blobs/sha256:4e83a61cd4894dea2942520f9147fdaa1e92b71089f288f
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/lzo/manifests/2.10
################################################################################################################# 100.0%
==> Fetching lzo
==> Downloading https://ghcr.io/v2/homebrew/core/lzo/blobs/sha256:8413f94bb69f337f7e1837e7f525e703cac105d27ceeb29de5c08c
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/pixman/manifests/0.42.2-1
################################################################################################################# 100.0%
==> Fetching pixman
==> Downloading https://ghcr.io/v2/homebrew/core/pixman/blobs/sha256:9cf9d788868c9609f6e3ea3798d93076c7b2b1b8ac7f63527f7
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/cairo/manifests/1.18.0
################################################################################################################# 100.0%
==> Fetching cairo
==> Downloading https://ghcr.io/v2/homebrew/core/cairo/blobs/sha256:35cd3a9f81432449e9b0f457a20c8e94e0d2c804da0210a5deff
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/shared-mime-info/manifests/2.4
################################################################################################################# 100.0%
==> Fetching shared-mime-info
==> Downloading https://ghcr.io/v2/homebrew/core/shared-mime-info/blobs/sha256:714303fdaefab5a012a1aa3d37243c02b1b4ff9bc
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/gdk-pixbuf/manifests/2.42.12
################################################################################################################# 100.0%
==> Fetching gdk-pixbuf
==> Downloading https://ghcr.io/v2/homebrew/core/gdk-pixbuf/blobs/sha256:1acee0ae28b67cd12f744e7923ff8a5e8c9396777af0bb6
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/fribidi/manifests/1.0.15
################################################################################################################# 100.0%
==> Fetching fribidi
==> Downloading https://ghcr.io/v2/homebrew/core/fribidi/blobs/sha256:f03a729ae535ac53791205a6be4e929e981fbd431c04eb2acb
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/graphite2/manifests/1.3.14
################################################################################################################# 100.0%
==> Fetching graphite2
==> Downloading https://ghcr.io/v2/homebrew/core/graphite2/blobs/sha256:0e811b079268bc99d1b6253fc0c979e76325e91e294fd059
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/harfbuzz/manifests/9.0.0
################################################################################################################# 100.0%
==> Fetching harfbuzz
==> Downloading https://ghcr.io/v2/homebrew/core/harfbuzz/blobs/sha256:3e2dc2ca41c19053edbef4c19808943597e6eda7530dd8940
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/pango/manifests/1.54.0
################################################################################################################# 100.0%
==> Fetching pango
==> Downloading https://ghcr.io/v2/homebrew/core/pango/blobs/sha256:3cdf86a860b1e40093330d83b705cfdc326f2974332d65565e2c
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/librsvg/manifests/2.58.2
################################################################################################################# 100.0%
==> Fetching librsvg
==> Downloading https://ghcr.io/v2/homebrew/core/librsvg/blobs/sha256:7e7f1595465d977cdfe14fb544005e129ee79ec719df45768b
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/m4/manifests/1.4.19
################################################################################################################# 100.0%
==> Fetching m4
==> Downloading https://ghcr.io/v2/homebrew/core/m4/blobs/sha256:f6d1087a51e0ff2e582b3043a25a51b67971b2246cf65167ef3abf1
################################################################################################################# 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libtool/manifests/2.4.7-1
################################################################################################################# 100.0%
==> Fetching libtool
==> Downloading https://ghcr.io/v2/homebrew/core/libtool/blobs/sha256:f55d5bcc07a45f599800b2c9fb5818c13be90803355e169cdb
################################################################################################################# 100.0%
==> Fetching graphviz
==> Downloading https://ghcr.io/v2/homebrew/core/graphviz/blobs/sha256:e3fba2a4b9202b094602c4d4edb887a0cece286f595057682
################################################################################################################# 100.0%
==> Installing dependencies for graphviz: libpng, freetype, util-linux, fontconfig, jpeg-turbo, brotli, giflib, highway, imath, lz4, zstd, libtiff, little-cms2, openexr, webp, ca-certificates, krb5, jpeg-xl, libvmaf, aom, libavif, gd, pcre2, dbus, glib, jasper, icu4c, libxml2, netpbm, gts, xorgproto, libxau, libxdmcp, libxcb, libx11, libxext, libxrender, lzo, pixman, cairo, shared-mime-info, gdk-pixbuf, fribidi, graphite2, harfbuzz, pango, librsvg, m4 and libtool
==> Installing graphviz dependency: libpng
==> Downloading https://ghcr.io/v2/homebrew/core/libpng/manifests/1.6.43
Already downloaded: /home/builder/.cache/Homebrew/downloads/dd618b09b8d6d4b89203b771528951e5309631cc3afd8dc1236f0e98965f2b67--libpng-1.6.43.bottle_manifest.json
==> Pouring libpng--1.6.43.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libpng/1.6.43: 29 files, 1.5MB
==> Installing graphviz dependency: freetype
==> Downloading https://ghcr.io/v2/homebrew/core/freetype/manifests/2.13.2-1
Already downloaded: /home/builder/.cache/Homebrew/downloads/8d6ca45fa8766fb544a5e6dbc76f0a68568656ab4fe1e837704491bb24e3035d--freetype-2.13.2-1.bottle_manifest.json
==> Pouring freetype--2.13.2.x86_64_linux.bottle.1.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/freetype/2.13.2: 69 files, 2.9MB
==> Installing graphviz dependency: util-linux
==> Downloading https://ghcr.io/v2/homebrew/core/util-linux/manifests/2.40.2
Already downloaded: /home/builder/.cache/Homebrew/downloads/fa5d89fc52ad95b143ba5ccb760a652f6802e63fc51edb4263ed60afb4fb7221--util-linux-2.40.2.bottle_manifest.json
==> Pouring util-linux--2.40.2.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/util-linux/2.40.2: 443 files, 25.7MB
==> Installing graphviz dependency: fontconfig
==> Downloading https://ghcr.io/v2/homebrew/core/fontconfig/manifests/2.15.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/33d176010dc9a105404ed23b6c0f8b853bf3a2df2e274876d412d7229a643320--fontconfig-2.15.0.bottle_manifest.json
==> Pouring fontconfig--2.15.0.x86_64_linux.bottle.tar.gz
==> Regenerating font cache, this may take a while
==> /home/linuxbrew/.linuxbrew/Cellar/fontconfig/2.15.0/bin/fc-cache -frv
🍺  /home/linuxbrew/.linuxbrew/Cellar/fontconfig/2.15.0: 96 files, 2.5MB
==> Installing graphviz dependency: jpeg-turbo
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-turbo/manifests/3.0.3
Already downloaded: /home/builder/.cache/Homebrew/downloads/d6b83c0ba8addc9c21ec2cf9fc969e5754261e7cf808fdf5925816b927875bb1--jpeg-turbo-3.0.3.bottle_manifest.json
==> Pouring jpeg-turbo--3.0.3.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/jpeg-turbo/3.0.3: 45 files, 4.7MB
==> Installing graphviz dependency: brotli
==> Downloading https://ghcr.io/v2/homebrew/core/brotli/manifests/1.1.0-1
Already downloaded: /home/builder/.cache/Homebrew/downloads/565098509cdfa90593ec9a41b41239f073843f88caed60ddaa3e6194ac4defda--brotli-1.1.0-1.bottle_manifest.json
==> Pouring brotli--1.1.0.x86_64_linux.bottle.1.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/brotli/1.1.0: 25 files, 983.7KB
==> Installing graphviz dependency: giflib
==> Downloading https://ghcr.io/v2/homebrew/core/giflib/manifests/5.2.2
Already downloaded: /home/builder/.cache/Homebrew/downloads/283773c4d2db4fe867419d7eea6811a6417889d78fad8871041c07f49b22d2a1--giflib-5.2.2.bottle_manifest.json
==> Pouring giflib--5.2.2.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/giflib/5.2.2: 27 files, 562.6KB
==> Installing graphviz dependency: highway
==> Downloading https://ghcr.io/v2/homebrew/core/highway/manifests/1.2.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/8cb1608f21fba449c4e34b0a4912e3d73b6f2fa2577c916720799b5057207452--highway-1.2.0.bottle_manifest.json
==> Pouring highway--1.2.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/highway/1.2.0: 75 files, 8.0MB
==> Installing graphviz dependency: imath
==> Downloading https://ghcr.io/v2/homebrew/core/imath/manifests/3.1.11
Already downloaded: /home/builder/.cache/Homebrew/downloads/4738c3b3aeed35cc9103ddfda8626c334457672a7e704d000247ccc8f1fddee9--imath-3.1.11.bottle_manifest.json
==> Pouring imath--3.1.11.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/imath/3.1.11: 50 files, 955.4KB
==> Installing graphviz dependency: lz4
==> Downloading https://ghcr.io/v2/homebrew/core/lz4/manifests/1.9.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/379e59b981667f9585b33a2ff318769d8edca3ce6fd2e9a67ed291ae3e0cc872--lz4-1.9.4.bottle_manifest.json
==> Pouring lz4--1.9.4.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/lz4/1.9.4: 23 files, 697.8KB
==> Installing graphviz dependency: zstd
==> Downloading https://ghcr.io/v2/homebrew/core/zstd/manifests/1.5.6
Already downloaded: /home/builder/.cache/Homebrew/downloads/29403e0df5404d8aeca0e750ac135ec9ef44fc5eeb6df69170ed602acabf0ffb--zstd-1.5.6.bottle_manifest.json
==> Pouring zstd--1.5.6.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/zstd/1.5.6: 32 files, 2.9MB
==> Installing graphviz dependency: libtiff
==> Downloading https://ghcr.io/v2/homebrew/core/libtiff/manifests/4.6.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/9c8455a2f6bcea7bf3e3461218fba309141b0b0553b6e1afc5fe64e63caccff3--libtiff-4.6.0.bottle_manifest.json
==> Pouring libtiff--4.6.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libtiff/4.6.0: 417 files, 6.9MB
==> Installing graphviz dependency: little-cms2
==> Downloading https://ghcr.io/v2/homebrew/core/little-cms2/manifests/2.16
Already downloaded: /home/builder/.cache/Homebrew/downloads/c4e2b31b0daade62da1f3c2e57d69f74987bac35310011b87220145fa60b3558--little-cms2-2.16.bottle_manifest.json
==> Pouring little-cms2--2.16.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/little-cms2/2.16: 24 files, 1.6MB
==> Installing graphviz dependency: openexr
==> Downloading https://ghcr.io/v2/homebrew/core/openexr/manifests/3.2.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/64b203875dbfc58a68a1ab1bee0b9dcfa77a93c55c283a295b618ea0434c8060--openexr-3.2.4.bottle_manifest.json
==> Pouring openexr--3.2.4.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/openexr/3.2.4: 206 files, 9.0MB
==> Installing graphviz dependency: webp
==> Downloading https://ghcr.io/v2/homebrew/core/webp/manifests/1.4.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/4fd3ea2923bb7885c84ba3eee4738315675acd20fdff772153a63d8087daa4ad--webp-1.4.0.bottle_manifest.json
==> Pouring webp--1.4.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/webp/1.4.0: 63 files, 3MB
==> Installing graphviz dependency: ca-certificates
==> Downloading https://ghcr.io/v2/homebrew/core/ca-certificates/manifests/2024-07-02
Already downloaded: /home/builder/.cache/Homebrew/downloads/f1e786c502c23070efef1c7716aeaea181b28fd0cdbc5327d6d7c243b49e7700--ca-certificates-2024-07-02.bottle_manifest.json
==> Pouring ca-certificates--2024-07-02.all.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/ca-certificates/2024-07-02: 4 files, 246.9KB
==> Installing graphviz dependency: krb5
==> Downloading https://ghcr.io/v2/homebrew/core/krb5/manifests/1.21.3
Already downloaded: /home/builder/.cache/Homebrew/downloads/c5793441ca90aa09420dddd84f19d4aaf86da4f0b3f60c84940d77b1cb4c6863--krb5-1.21.3.bottle_manifest.json
==> Pouring krb5--1.21.3.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/krb5/1.21.3: 164 files, 5.3MB
==> Installing graphviz dependency: jpeg-xl
==> Downloading https://ghcr.io/v2/homebrew/core/jpeg-xl/manifests/0.10.3
Already downloaded: /home/builder/.cache/Homebrew/downloads/aa06e1f8295ebf7ba2902b7732126f23b5e34e5ba8f0b2a740be9d8870092f00--jpeg-xl-0.10.3.bottle_manifest.json
==> Pouring jpeg-xl--0.10.3.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/jpeg-xl/0.10.3: 63 files, 49.5MB
==> Installing graphviz dependency: libvmaf
==> Downloading https://ghcr.io/v2/homebrew/core/libvmaf/manifests/3.0.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/6bf89f1d683f34ff5b4c58275236e1f038d5d8189e538795d9af83e07d4c8404--libvmaf-3.0.0.bottle_manifest.json
==> Pouring libvmaf--3.0.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libvmaf/3.0.0: 236 files, 7.6MB
==> Installing graphviz dependency: aom
==> Downloading https://ghcr.io/v2/homebrew/core/aom/manifests/3.9.1
Already downloaded: /home/builder/.cache/Homebrew/downloads/42dbe5f4422a19256563083479e5f427b220a06a6c6c4e5511a4961dd9d7ef72--aom-3.9.1.bottle_manifest.json
==> Pouring aom--3.9.1.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/aom/3.9.1: 24 files, 14.4MB
==> Installing graphviz dependency: libavif
==> Downloading https://ghcr.io/v2/homebrew/core/libavif/manifests/1.0.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/be5adfc796abe915819451a1488fc3b9f68d320a8bb92c451c21f450b4e4e672--libavif-1.0.4.bottle_manifest.json
==> Pouring libavif--1.0.4.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libavif/1.0.4: 20 files, 646.3KB
==> Installing graphviz dependency: gd
==> Downloading https://ghcr.io/v2/homebrew/core/gd/manifests/2.3.3_6
Already downloaded: /home/builder/.cache/Homebrew/downloads/1f63d9efd8c74faa4477bd8b8a3970abd38e51230ed052918bb6f3715aab8b61--gd-2.3.3_6.bottle_manifest.json
==> Pouring gd--2.3.3_6.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/gd/2.3.3_6: 35 files, 1.4MB
==> Installing graphviz dependency: pcre2
==> Downloading https://ghcr.io/v2/homebrew/core/pcre2/manifests/10.44
Already downloaded: /home/builder/.cache/Homebrew/downloads/22ed791461c5bf400adde8c3b432c1230866aa1db3c5cb81e06a6ff21cac96ee--pcre2-10.44.bottle_manifest.json
==> Pouring pcre2--10.44.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/pcre2/10.44: 241 files, 7.3MB
==> Installing graphviz dependency: dbus
==> Downloading https://ghcr.io/v2/homebrew/core/dbus/manifests/1.14.10
Already downloaded: /home/builder/.cache/Homebrew/downloads/2dee97539c09d15349d9935f14c299bce3e52d11fd6d399a05a5190d0e7a1028--dbus-1.14.10.bottle_manifest.json
==> Pouring dbus--1.14.10.x86_64_linux.bottle.tar.gz
==> /home/linuxbrew/.linuxbrew/Cellar/dbus/1.14.10/bin/dbus-uuidgen --ensure=/home/linuxbrew/.linuxbrew/var/lib/dbus/mac
🍺  /home/linuxbrew/.linuxbrew/Cellar/dbus/1.14.10: 78 files, 2.9MB
==> Installing graphviz dependency: glib
==> Downloading https://ghcr.io/v2/homebrew/core/glib/manifests/2.80.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/f635cb07f35354f1ef636173e4d8f0e85a3bd09d85784c8639a201b1c5263742--glib-2.80.4.bottle_manifest.json
==> Pouring glib--2.80.4.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/glib/2.80.4: 534 files, 40.6MB
==> Installing graphviz dependency: jasper
==> Downloading https://ghcr.io/v2/homebrew/core/jasper/manifests/4.2.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/0edc7047fdbd9e0fd88f4c5ceed204b57e9b4d4f42c1b1b21c502d68fce31118--jasper-4.2.4.bottle_manifest.json
==> Pouring jasper--4.2.4.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/jasper/4.2.4: 43 files, 2.0MB
==> Installing graphviz dependency: icu4c
==> Downloading https://ghcr.io/v2/homebrew/core/icu4c/manifests/74.2
Already downloaded: /home/builder/.cache/Homebrew/downloads/3e5230e726e5548db28bc0cf75710d6405903b742f941113d3dbe7483fad72a4--icu4c-74.2.bottle_manifest.json
==> Pouring icu4c--74.2.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/icu4c/74.2: 271 files, 85.0MB
==> Installing graphviz dependency: libxml2
==> Downloading https://ghcr.io/v2/homebrew/core/libxml2/manifests/2.12.8
Already downloaded: /home/builder/.cache/Homebrew/downloads/957db51bbddf4033531b014eaff4b0d1b1472aa78abd3aa8c909b25b37b9cd8b--libxml2-2.12.8.bottle_manifest.json
==> Pouring libxml2--2.12.8.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxml2/2.12.8: 202 files, 8.4MB
==> Installing graphviz dependency: netpbm
==> Downloading https://ghcr.io/v2/homebrew/core/netpbm/manifests/11.02.09
Already downloaded: /home/builder/.cache/Homebrew/downloads/1c4be61c6a2db4fdbc7e0252e62cd50fb8296d87a1cc919668ac3c70c6ff7e7f--netpbm-11.02.09.bottle_manifest.json
==> Pouring netpbm--11.02.09.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/netpbm/11.02.09: 417 files, 9.8MB
==> Installing graphviz dependency: gts
==> Downloading https://ghcr.io/v2/homebrew/core/gts/manifests/0.7.6_3
Already downloaded: /home/builder/.cache/Homebrew/downloads/0cb7519523b42ff855917c33218c1ef771e3060080fea895de59eb848c833cd1--gts-0.7.6_3.bottle_manifest.json
==> Pouring gts--0.7.6_3.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/gts/0.7.6_3: 28 files, 1.7MB
==> Installing graphviz dependency: xorgproto
==> Downloading https://ghcr.io/v2/homebrew/core/xorgproto/manifests/2024.1
Already downloaded: /home/builder/.cache/Homebrew/downloads/d89d69340366d1d015e7214520f64081e2d82d7955fb28c6ea5f6539dcb610b2--xorgproto-2024.1.bottle_manifest.json
==> Pouring xorgproto--2024.1.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/xorgproto/2024.1: 268 files, 4MB
==> Installing graphviz dependency: libxau
==> Downloading https://ghcr.io/v2/homebrew/core/libxau/manifests/1.0.11
Already downloaded: /home/builder/.cache/Homebrew/downloads/7faff26297b2e07682655beaa529cff7b3de0ad1abc013863ca3d03602b79ee7--libxau-1.0.11.bottle_manifest.json
==> Pouring libxau--1.0.11.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxau/1.0.11: 22 files, 142.9KB
==> Installing graphviz dependency: libxdmcp
==> Downloading https://ghcr.io/v2/homebrew/core/libxdmcp/manifests/1.1.5
Already downloaded: /home/builder/.cache/Homebrew/downloads/8713e53f73d0be64780dbea522b0ee07027e6cc7828ff1a4fa0a6596f14cfe25--libxdmcp-1.1.5.bottle_manifest.json
==> Pouring libxdmcp--1.1.5.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxdmcp/1.1.5: 13 files, 152.9KB
==> Installing graphviz dependency: libxcb
==> Downloading https://ghcr.io/v2/homebrew/core/libxcb/manifests/1.17.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/90067be44989a7a337e7fa793989a66b6f8bfc1edfc82925162cab273ee94879--libxcb-1.17.0.bottle_manifest.json
==> Pouring libxcb--1.17.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxcb/1.17.0: 2,498 files, 7.0MB
==> Installing graphviz dependency: libx11
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/manifests/1.8.9
Already downloaded: /home/builder/.cache/Homebrew/downloads/ca292424919f76deb4667ed9445ade03489260780e6a18b3683e112aea943130--libx11-1.8.9.bottle_manifest.json
==> Pouring libx11--1.8.9.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libx11/1.8.9: 1,050 files, 8MB
==> Installing graphviz dependency: libxext
==> Downloading https://ghcr.io/v2/homebrew/core/libxext/manifests/1.3.6
Already downloaded: /home/builder/.cache/Homebrew/downloads/fedb843acbfcf682fb451396914bfc096f9ea2748376d4c43ce2af7ce1b766b7--libxext-1.3.6.bottle_manifest.json
==> Pouring libxext--1.3.6.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxext/1.3.6: 89 files, 519.4KB
==> Installing graphviz dependency: libxrender
==> Downloading https://ghcr.io/v2/homebrew/core/libxrender/manifests/0.9.11
Already downloaded: /home/builder/.cache/Homebrew/downloads/134c11be8346a1b116e04983c2da6366f29c4f4c2abc17604dcdb80d0475ae9d--libxrender-0.9.11.bottle_manifest.json
==> Pouring libxrender--0.9.11.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxrender/0.9.11: 14 files, 254.3KB
==> Installing graphviz dependency: lzo
==> Downloading https://ghcr.io/v2/homebrew/core/lzo/manifests/2.10
Already downloaded: /home/builder/.cache/Homebrew/downloads/d4aa5b0c239912c53bc857d1012c6b7feb4acb509618f5e100f95bf8521f08e7--lzo-2.10.bottle_manifest.json
==> Pouring lzo--2.10.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/lzo/2.10: 33 files, 691KB
==> Installing graphviz dependency: pixman
==> Downloading https://ghcr.io/v2/homebrew/core/pixman/manifests/0.42.2-1
Already downloaded: /home/builder/.cache/Homebrew/downloads/2b0d8f2c63712ce503fa54309b732051a7ca5cd31bd561aa4aaba331bf26bcef--pixman-0.42.2-1.bottle_manifest.json
==> Pouring pixman--0.42.2.x86_64_linux.bottle.1.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/pixman/0.42.2: 12 files, 1.7MB
==> Installing graphviz dependency: cairo
==> Downloading https://ghcr.io/v2/homebrew/core/cairo/manifests/1.18.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/1b8b7f19e38cb0e029497dfe0ad3f3557f605025c5575bdfe86c17b889c6e6d1--cairo-1.18.0.bottle_manifest.json
==> Pouring cairo--1.18.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/cairo/1.18.0: 51 files, 2.5MB
==> Installing graphviz dependency: shared-mime-info
==> Downloading https://ghcr.io/v2/homebrew/core/shared-mime-info/manifests/2.4
Already downloaded: /home/builder/.cache/Homebrew/downloads/b939513ada122d80abd08624d26056d1bf65b49a2b2ed794db163a91db90dbab--shared-mime-info-2.4.bottle_manifest.json
==> Pouring shared-mime-info--2.4.x86_64_linux.bottle.tar.gz
==> /home/linuxbrew/.linuxbrew/Cellar/shared-mime-info/2.4/bin/update-mime-database /home/linuxbrew/.linuxbrew/share/mim
🍺  /home/linuxbrew/.linuxbrew/Cellar/shared-mime-info/2.4: 89 files, 5.3MB
==> Installing graphviz dependency: gdk-pixbuf
==> Downloading https://ghcr.io/v2/homebrew/core/gdk-pixbuf/manifests/2.42.12
Already downloaded: /home/builder/.cache/Homebrew/downloads/51502ca3ad1b3a076e2aec3be882089fbd1c2257b822a0d3c155e23e68a7e70e--gdk-pixbuf-2.42.12.bottle_manifest.json
==> Pouring gdk-pixbuf--2.42.12.x86_64_linux.bottle.tar.gz
==> /home/linuxbrew/.linuxbrew/Cellar/gdk-pixbuf/2.42.12/bin/gdk-pixbuf-query-loaders --update-cache
🍺  /home/linuxbrew/.linuxbrew/Cellar/gdk-pixbuf/2.42.12: 153 files, 4.4MB
==> Installing graphviz dependency: fribidi
==> Downloading https://ghcr.io/v2/homebrew/core/fribidi/manifests/1.0.15
Already downloaded: /home/builder/.cache/Homebrew/downloads/c743b3178050604a607c1ebc433b1b187bb5250afa047857b62467fb9f62249a--fribidi-1.0.15.bottle_manifest.json
==> Pouring fribidi--1.0.15.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/fribidi/1.0.15: 69 files, 739.3KB
==> Installing graphviz dependency: graphite2
==> Downloading https://ghcr.io/v2/homebrew/core/graphite2/manifests/1.3.14
Already downloaded: /home/builder/.cache/Homebrew/downloads/bbb4dd2ef1846301d1eb08053e19e11ca9c780f93f4d3b2d638fd94a9bf54a0c--graphite2-1.3.14.bottle_manifest.json
==> Pouring graphite2--1.3.14.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/graphite2/1.3.14: 19 files, 330KB
==> Installing graphviz dependency: harfbuzz
==> Downloading https://ghcr.io/v2/homebrew/core/harfbuzz/manifests/9.0.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/0219cb6f20bb981be0693962274cb149fe97addca84cbcc09f4cc1251bb3348c--harfbuzz-9.0.0.bottle_manifest.json
==> Pouring harfbuzz--9.0.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/harfbuzz/9.0.0: 81 files, 11.1MB
==> Installing graphviz dependency: pango
==> Downloading https://ghcr.io/v2/homebrew/core/pango/manifests/1.54.0
Already downloaded: /home/builder/.cache/Homebrew/downloads/06c4532b8d175a9098d6a1c5b6b1d2b154b126fef30ddbb5b26791e86b8c9675--pango-1.54.0.bottle_manifest.json
==> Pouring pango--1.54.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/pango/1.54.0: 72 files, 3.7MB
==> Installing graphviz dependency: librsvg
==> Downloading https://ghcr.io/v2/homebrew/core/librsvg/manifests/2.58.2
Already downloaded: /home/builder/.cache/Homebrew/downloads/6a8b85c0b7867d8dc503754343fbefcd02e27d8e623bec37f8a0f43a58097fa3--librsvg-2.58.2.bottle_manifest.json
==> Pouring librsvg--2.58.2.x86_64_linux.bottle.tar.gz
==> /home/linuxbrew/.linuxbrew/opt/gdk-pixbuf/bin/gdk-pixbuf-query-loaders --update-cache
🍺  /home/linuxbrew/.linuxbrew/Cellar/librsvg/2.58.2: 24 files, 61MB
==> Installing graphviz dependency: m4
==> Downloading https://ghcr.io/v2/homebrew/core/m4/manifests/1.4.19
Already downloaded: /home/builder/.cache/Homebrew/downloads/5b2a7f715487b7377e409e8ca58569040cd89f33859f691210c58d94410fd33b--m4-1.4.19.bottle_manifest.json
==> Pouring m4--1.4.19.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/m4/1.4.19: 40 files, 1.1MB
==> Installing graphviz dependency: libtool
==> Downloading https://ghcr.io/v2/homebrew/core/libtool/manifests/2.4.7-1
Already downloaded: /home/builder/.cache/Homebrew/downloads/606e79b61b857bc4e83f71abf7afa8e087c4ad71539989e7066a4055439bf129--libtool-2.4.7-1.bottle_manifest.json
==> Pouring libtool--2.4.7.x86_64_linux.bottle.1.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libtool/2.4.7: 75 files, 3.8MB
==> Installing graphviz
==> Pouring graphviz--12.0.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/graphviz/12.0.0: 296 files, 7MB
==> Running `brew cleanup graphviz`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
Error: no implicit conversion of false into String
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/utils/popen.rb:47:in `initialize'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/utils/popen.rb:47:in `popen'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/utils/popen.rb:47:in `popen'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/utils/popen.rb:9:in `popen_read'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/ld.rb:13:in `brewed_ld_so_diagnostics'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/ld.rb:23:in `sysconfdir'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/ld.rb:44:in `library_paths'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:165:in `find_full_lib_path'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:131:in `block in initialize'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:131:in `map'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:131:in `initialize'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:213:in `new'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:213:in `metadata'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/os/linux/elf.rb:222:in `dynamically_linked_libraries'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/linkage_checker.rb:115:in `block in check_dylibs'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/pathname.rb:577:in `block in find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/find.rb:51:in `block (2 levels) in find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/find.rb:50:in `catch'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/find.rb:50:in `block in find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/find.rb:45:in `each'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/find.rb:45:in `find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/pathname.rb:577:in `find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/lib/ruby/3.3.0/forwardable.rb:240:in `find'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/linkage_checker.rb:108:in `check_dylibs'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/extend/os/linux/linkage_checker.rb:32:in `check_dylibs'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/linkage_checker.rb:32:in `initialize'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:261:in `new'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:261:in `block (2 levels) in check_broken_dependents'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:256:in `select'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:256:in `block in check_broken_dependents'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/cache_store.rb:26:in `use'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:253:in `check_broken_dependents'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/upgrade.rb:306:in `check_installed_dependents'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/cmd/install.rb:320:in `run'
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/brew.rb:92:in `<main>'
Please report this issue:
  https://docs.brew.sh/Troubleshooting

That didn’t work. I did a mix of sudo apt install graphviz as well as sudo apt install xdg-utils.

I also needed to set my PYTHONPATH. This was the key thing blocking me

$ export PYTHONPATH=/usr/local/lib/python3.10/dist-packages

After I installed Firefox, i could get Graphviz at least to work

$ cat diagram-sample2.py
from graphviz import Digraph

# Create a new directed graph
dot = Digraph('aws_diagram')

# Add nodes for ELB, EC2, and RDS
dot.node('A', 'ELB')
dot.node('B', 'EC2')
dot.node('C', 'RDS')

# Add edges between the nodes
dot.edges(['AB', 'BC'])

# Save the diagram to a file
dot.render('aws_diagram.gv', view=True)

Now we can build and run

builder@LuiGi:~/Workspaces/diagrams$ python3 ./diagram-sample2.py
builder@LuiGi:~/Workspaces/diagrams$ Error: no "view" mailcap rules found for type "application/pdf"
WARNING: You don't seem to have any mimeinfo.cache files.
Try running the update-desktop-database command. If you
don't have this command you should install the
desktop-file-utils package. This package is available from
http://freedesktop.org/wiki/Software/desktop-file-utils/
No applications found for mimetype: application/pdf
.[42151, Main Thread] WARNING: Failed to read portal settings: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.portal.Desktop was not provided by any .service files: 'glib warning', file /build/firefox/parts/firefox/build/toolkit/xre/nsSigHandlers.cpp:187

(firefox:42151): Gdk-WARNING **: 08:45:49.309: Failed to read portal settings: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.portal.Desktop was not provided by any .service files
[Parent 42151, Main Thread] WARNING: Failed to mkdir /home/builder/snap/firefox/4539/.config/ibus/bus: Not a directory: 'glib warning', file /build/firefox/parts/firefox/build/toolkit/xre/nsSigHandlers.cpp:187

(firefox:42151): IBUS-WARNING **: 08:45:50.544: Failed to mkdir /home/builder/snap/firefox/4539/.config/ibus/bus: Not a directory

/content/images/2024/07/graphviz-01.png

With Firefox now in WSL, let me try again

builder@LuiGi:~/Workspaces/diagrams$ cat diagram-sample.py
# diagram.py
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Web Service", show=False):
        ELB("ELB") >> EC2("Web") >> RDS("Users DB")

I’ll compile:

builder@LuiGi:~/Workspaces/diagrams$ python3 ./diagram-sample.py

Then launch in Firefox

/content/images/2024/07/graphviz-02.png

GCP Diagrams

We can do similar with GCP.

There is no bi-directional arrow, so you can either use two blocks or use - for an arrow-less line

# diagram.py
from diagrams import Diagram
from diagrams.gcp.compute import GCE 
from diagrams.gcp.database import SQL
from diagrams.gcp.network import LoadBalancing

with Diagram("Web Service", show=True, direction="LR"):
        LoadBalancing("External LB") >> GCE ("uMIG backend pool") >> GCE("VM") >> SQL("CloudSQL")
        SQL("CloudSQL") >> GCE("VM") 

/content/images/2024/07/graphviz-03.png

You won’t see too many AI posts on this blog because I’m rather Bearish on AI. However, there is a good case for using AI to help craft a start point for a bigger diagram

/content/images/2024/07/graphviz-04.png

It wasn’t perfect, but it’s good enough to get a start. Once I figured out that a list cannot directly link to a list, I worked it out

from diagrams import Cluster, Diagram
from diagrams.gcp.network import LoadBalancing
from diagrams.gcp.compute import GKE
from diagrams.onprem.network import Istio
from diagrams.k8s.network import SVC
from diagrams.k8s.compute import Pod

with Diagram("GCP Architecture", show=True):
    load_balancer = LoadBalancing("Load Balancer")

    with Cluster("GKE Cluster"):
        gke = GKE("GKE")
        istio = Istio("Istio")
        istio2 = Istio("Istio")

        with Cluster("Services"):
            svc_group = [SVC("service1"), SVC("service2")]

        with Cluster("Pods"):
            pod_group = [Pod("pod1"), Pod("pod2")]

    load_balancer >> gke >> istio >> svc_group >> istio2 >> pod_group

And tested with a new python file

s$ python3 ./diagram-gcp2.py
builder@LuiGi:~/Workspaces/diagrams$ [92988, Main Thread] WARNING: Failed to read portal settings: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.portal.Desktop was not provided by any .service files: 'glib warning', file /build/firefox/parts/firefox/build/toolkit/xre/nsSigHandlers.cpp:187

(firefox:92988): Gdk-WARNING **: 10:20:15.594: Failed to read portal settings: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.portal.Desktop was not provided by any .service files
[Parent 92988, Main Thread] WARNING: Failed to mkdir /home/builder/snap/firefox/4539/.config/ibus/bus: Not a directory: 'glib warning', file /build/firefox/parts/firefox/build/toolkit/xre/nsSigHandlers.cpp:187

(firefox:92988): IBUS-WARNING **: 10:20:15.809: Failed to mkdir /home/builder/snap/firefox/4539/.config/ibus/bus: Not a directory

/content/images/2024/07/graphviz-05.png

Gemini Code Assist

As we just used Co-Pilot, I figured I would let Gemini at the problem as well

/content/images/2024/07/graphviz-06.png

with some tweaks, I got it to launch. I do find it a bit unwieldy to read:

from diagrams import Diagram
from diagrams.gcp.compute import GKE
from diagrams.gcp.network import FirewallRules, LoadBalancing
from diagrams.onprem.client import User
from diagrams.onprem.network import  Internet
from diagrams.gcp.database import SQL

with Diagram("GCP Load Balancer with Istio on GKE", show=True):
    users = User("Users")
    internet = Internet("Internet")
    firewall = FirewallRules("FirewallRules")
    lb = LoadBalancing("Load Balancer")
    gke = GKE("GKE Cluster")
    istio = gke >> GKE("Istio")
    virtual_service = istio >> GKE("Virtual Service")
    service_a = istio >> GKE("Service A")
    service_b = istio >> GKE("Service B")
    database = SQL("SQL")

    internet >> firewall >> lb
    lb >> virtual_service
    virtual_service >> service_a
    virtual_service >> service_b
    service_a >> database
    service_b >> database
    users >> service_a
    users >> service_b

/content/images/2024/07/graphviz-07.png

Switching to TB (top to bottom) does make it easier to read

from diagrams import Diagram
from diagrams.gcp.compute import GKE
from diagrams.gcp.network import FirewallRules, LoadBalancing
from diagrams.onprem.client import User
from diagrams.onprem.network import  Internet
from diagrams.gcp.database import SQL

with Diagram("GCP Load Balancer with Istio on GKE", direction="TB", show=True):
    users = User("Users")
    internet = Internet("Internet")
    firewall = FirewallRules("FirewallRules")
    lb = LoadBalancing("Load Balancer")
    gke = GKE("GKE Cluster")
    istio = gke >> GKE("Istio")
    virtual_service = istio >> GKE("Virtual Service")
    service_a = istio >> GKE("Service A")
    service_b = istio >> GKE("Service B")
    database = SQL("SQL")

    internet >> firewall >> lb
    lb >> virtual_service
    virtual_service >> service_a
    virtual_service >> service_b
    service_a >> database
    service_b >> database
    users >> service_a
    users >> service_b

/content/images/2024/07/graphviz-08.png

That also highlights a bit of a mistake in that users should come from the internet.

from diagrams import Diagram
from diagrams.gcp.compute import GKE
from diagrams.gcp.network import FirewallRules, LoadBalancing
from diagrams.onprem.client import User
from diagrams.onprem.network import  Internet
from diagrams.gcp.database import SQL

with Diagram("GCP Load Balancer with Istio on GKE", direction="TB", show=True):
    users = User("Users")
    internet = Internet("Internet")
    firewall = FirewallRules("FirewallRules")
    lb = LoadBalancing("Load Balancer")
    gke = GKE("GKE Cluster")
    istio = gke >> GKE("Istio")
    virtual_service = istio >> GKE("Virtual Service")
    service_a = istio >> GKE("Service A")
    service_b = istio >> GKE("Service B")
    database = SQL("SQL")

    users >> internet
    internet >> firewall >> lb
    lb >> virtual_service
    virtual_service >> service_a
    virtual_service >> service_b
    service_a >> database
    service_b >> database

This diagram makes more sense:

/content/images/2024/07/graphviz-09.png

I could keep refining it - turn GKE into a block, Show the LB tying to Istio which in turn goes to Virtual Services, but it would be enough for a start which is really what we are asking the AI to provide for us.

Azure

I asked Copilot to generate me a similar diagram in Azure:

It came back with (actually it used “KeyVault” instead of “KeyVaults”, but i fixed that error)

from diagrams import Cluster, Diagram
from diagrams.azure.compute import AKS
from diagrams.azure.network import LoadBalancers, VirtualNetworks
from diagrams.azure.security import KeyVaults
from diagrams.onprem.network import Istio
from diagrams.k8s.compute import Pod
from diagrams.k8s.network import SVC

with Diagram("Azure Architecture", show=True):
    load_balancer = LoadBalancers("Load Balancer")
    virtual_network = VirtualNetworks("Virtual Network")
    key_vault = KeyVaults("AKV")

    with Cluster("AKS Cluster"):
        aks = AKS("AKS")
        istio = Istio("Istio")

        with Cluster("Node Pools"):
            node_pools = [Pod("Node Pool 1"), Pod("Node Pool 2")]

        with Cluster("Services"):
            svc_group = [SVC("service1"), SVC("service2")]

    load_balancer >> virtual_network >> aks >> node_pools >> istio >> svc_group >> key_vault

Which looks pretty good

/content/images/2024/07/graphviz-10.png

Hedge Doc

We know that Hedgedoc can handle inline Graphviz, but how close are these two?

For instance, say we built out the following Graphviz:

digraph {
        U [label=User shape=ellipse]
        ALB [label="Azure
Load Balancer"]
        WAS [label="Web App
Service"]
        ASD [label="Azure SQL
Database"]
        ARC [label="Azure Redis
Cache"]
        AS [label="Azure
Storage"]
        U -> ALB [label="HTTP/HTTPS"]
        ALB -> WAS [label="Route traffic"]
        WAS -> ASD [label="Read/Write Data"]
        WAS -> ARC [label="Cache Data"]
        WAS -> AS [label="Store Files"]
}

I can see that rendered in Hedgedoc

/content/images/2024/07/graphviz-11.png

I can also use Python in much the same way:

builder@LuiGi:~/Workspaces/diagrams$ cat diagram-azure2.py
from graphviz import Digraph

# Create a new directed graph
dot = Digraph()

# Define nodes
dot.node('U', 'User', shape='ellipse')
dot.node('ALB', 'Azure\nLoad Balancer')
dot.node('WAS', 'Web App\nService')
dot.node('ASD', 'Azure SQL\nDatabase')
dot.node('ARC', 'Azure Redis\nCache')
dot.node('AS', 'Azure\nStorage')

# Define edges
dot.edge('U', 'ALB', label='HTTP/HTTPS')
dot.edge('ALB', 'WAS', label='Route traffic')
dot.edge('WAS', 'ASD', label='Read/Write Data')
dot.edge('WAS', 'ARC', label='Cache Data')
dot.edge('WAS', 'AS', label='Store Files')

# Print the dot graph
print(dot.source)

Which will generate that same block of Hedgedoc compatible Graphviz

builder@LuiGi:~/Workspaces/diagrams$ python3 ./diagram-azure2.py
digraph {
        U [label=User shape=ellipse]
        ALB [label="Azure
Load Balancer"]
        WAS [label="Web App
Service"]
        ASD [label="Azure SQL
Database"]
        ARC [label="Azure Redis
Cache"]
        AS [label="Azure
Storage"]
        U -> ALB [label="HTTP/HTTPS"]
        ALB -> WAS [label="Route traffic"]
        WAS -> ASD [label="Read/Write Data"]
        WAS -> ARC [label="Cache Data"]
        WAS -> AS [label="Store Files"]
}

But while similar, these are not identical.

For instance, the first Azure code we did with all the nice icons

from diagrams import Cluster, Diagram
from diagrams.azure.compute import AKS
from diagrams.azure.network import LoadBalancers, VirtualNetworks
from diagrams.azure.security import KeyVaults
from diagrams.onprem.network import Istio
from diagrams.k8s.compute import Pod
from diagrams.k8s.network import SVC

with Diagram("Azure Architecture", show=True):
    load_balancer = LoadBalancers("Load Balancer")
    virtual_network = VirtualNetworks("Virtual Network")
    key_vault = KeyVaults("AKV")

    with Cluster("AKS Cluster"):
        aks = AKS("AKS")
        istio = Istio("Istio")

        with Cluster("Node Pools"):
            node_pools = [Pod("Node Pool 1"), Pod("Node Pool 2")]

        with Cluster("Services"):
            svc_group = [SVC("service1"), SVC("service2")]

    load_balancer >> virtual_network >> aks >> node_pools >> istio >> svc_group >> key_vault

Translates to a functional, albeit less “pretty” diagram in Graphviz

digraph "Azure Architecture" {
    graph [rankdir=LR];
    node [shape=box];

    // Define nodes
    "Load Balancer" [label="Load Balancer"];
    "Virtual Network" [label="Virtual Network"];
    "AKV" [label="AKV"];
    "AKS" [label="AKS"];
    "Istio" [label="Istio"];
    "Node Pool 1" [label="Node Pool 1"];
    "Node Pool 2" [label="Node Pool 2"];
    "service1" [label="service1"];
    "service2" [label="service2"];

    // Define edges
    "Load Balancer" -> "Virtual Network";
    "Virtual Network" -> "AKS";
    "AKS" -> "Node Pool 1";
    "AKS" -> "Node Pool 2";
    "Node Pool 1" -> "Istio";
    "Node Pool 2" -> "Istio";
    "Istio" -> "service1";
    "Istio" -> "service2";
    "service1" -> "AKV";
    "service2" -> "AKV";
}

/content/images/2024/07/graphviz-12.png

Pipelines

Let’s look at how we might generate these in a pipeline.

We’ll use a Github workflow for this in a new Github repo

name: Diagram Workflow

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up Python 3
      uses: actions/setup-python@v2
      with:
        python-version: '3.x'

    - name: Install dependencies (Graphviz)
      run: |
        sudo apt update -y
        sudo apt install -y graphviz

    - name: Install dependencies (Diagrams)
      run: |
        python -m pip install --upgrade pip
        pip install diagrams
        pip install graphviz

    - name: Run script
      run: |
        # Ensure we are not set to launch a web browser
        find . -type f -name \*.py -exec sed -i 's/show=True/show=False/g' {} \; -print
        
        # Now generate the images
        python3 diagram-azure1.py

    - name: Create zip of PNG files
      run: |
        mkdir pngs
        mv *.png pngs/
        zip -r diagrams.zip pngs/

    - name: Upload artifacts
      uses: actions/upload-artifact@v2
      with:
        name: diagrams
        path: diagrams.zip

which completes in Github Actions

/content/images/2024/07/graphviz-13.png

On the details page I can see “Artifacts” at the bottom

/content/images/2024/07/graphviz-14.png

Which I can edit and see. This makes it handy if I want to create diagrams without having to setup a local environment

Web Options

To render straight Python Diagram I tried a few options.

Most Python web runners would not let me add packages.

/content/images/2024/07/graphviz-17.png

And the one that did seemed to time out

/content/images/2024/07/graphviz-16.png

I also figured a Jupyter Notebook might work. However, I don’t see any kind of output. Chances are I’m doing something wrong or I need the more full featured Notebooks (not Lite version)

/content/images/2024/07/graphviz-18.png

That said, there are Graphviz playgrounds like this one

/content/images/2024/07/graphviz-19.png

We could use that for the Azure output earlier to see a web render without needing Hedgedoc

/content/images/2024/07/graphviz-20.png

There are other web-based Graphviz renders such as webgraphviz.com and https://stamm-wilbrandt.de/GraphvizFiddle/

/content/images/2024/07/graphviz-21.png

I also wanted to point out http://www.ryandesign.com/canviz/ which just has a bunch of interesting examples I used for inspiration

/content/images/2024/07/graphviz-22.png

You can view the source after rendering any of them.

Summary

Today we looked at Diagrams in Python which is based on Graphviz but as we noticed, it’s slightly different. We experimented with some AI generation and looked at diagrams using some of the major cloud providers like Google and Azure. We then built out a pipeline that can render as artifacts and lastly touched on web applications, though focused ultimately more on Graphviz than Python Diagrams.

Overall, I really like Diagrams in Python. I often find myself copying and pasting icons into Google Drawings or into a slide in a PPT for a presentation and this seems far cleaner. For my professional side, I’m often dancing between Miro and Lucid. Arguably, if one has Lucid, that is a very excellent suite. But this provides a nice Open-Source option that can create quite elegant diagrams of cloud infrastructure.

Graphviz Diagrams Github AI Copilot Gemini Docker

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes