New Upstream Release - python-diagrams

Ready changes

Summary

Merged new upstream version: 0.23.1 (was: 0.21.1).

Resulting package

Built on 2022-12-31T01:33 (took 4m35s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases python3-diagrams

Lintian Result

Diff

diff --git a/PKG-INFO b/PKG-INFO
index 0ce2d12..aca7ef6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: diagrams
-Version: 0.21.1
+Version: 0.23.1
 Summary: Diagram as Code
 Home-page: https://diagrams.mingrammer.com
 License: MIT
@@ -9,11 +9,12 @@ Author-email: mingrammer@gmail.com
 Requires-Python: >=3.6,<4.0
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Requires-Dist: contextvars (>=2.4,<3.0); python_version >= "3.6" and python_version < "3.7"
 Requires-Dist: graphviz (>=0.13.2,<0.20.0)
 Requires-Dist: jinja2 (>=2.10,<4.0)
@@ -59,6 +60,7 @@ Diagrams lets you draw the cloud system architecture **in Python code**. It was
 ![generic provider](https://img.shields.io/badge/Generic-orange?color=5f87bf)
 ![programming provider](https://img.shields.io/badge/Programming-orange?color=5f87bf)
 ![saas provider](https://img.shields.io/badge/SaaS-orange?color=5f87bf)
+![c4 provider](https://img.shields.io/badge/C4-orange?color=5f87bf)
 
 ## Getting Started
 
@@ -105,7 +107,7 @@ To contribute to diagram, check out [contribution guidelines](CONTRIBUTING.md).
 
 ## Other languages
 
-- If you are familiar to Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.
+- If you are familiar with Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.
 
 ## License
 
diff --git a/README.md b/README.md
index 0633255..0b15594 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ Diagrams lets you draw the cloud system architecture **in Python code**. It was
 ![generic provider](https://img.shields.io/badge/Generic-orange?color=5f87bf)
 ![programming provider](https://img.shields.io/badge/Programming-orange?color=5f87bf)
 ![saas provider](https://img.shields.io/badge/SaaS-orange?color=5f87bf)
+![c4 provider](https://img.shields.io/badge/C4-orange?color=5f87bf)
 
 ## Getting Started
 
@@ -83,7 +84,7 @@ To contribute to diagram, check out [contribution guidelines](CONTRIBUTING.md).
 
 ## Other languages
 
-- If you are familiar to Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.
+- If you are familiar with Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.
 
 ## License
 
diff --git a/debian/changelog b/debian/changelog
index 5812d2b..87dec65 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-diagrams (0.23.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sat, 31 Dec 2022 01:30:02 -0000
+
 python-diagrams (0.21.1-1) unstable; urgency=medium
 
   * New upstream version 0.21.1
diff --git a/diagrams/__init__.py b/diagrams/__init__.py
index 1fb33db..b46fa46 100644
--- a/diagrams/__init__.py
+++ b/diagrams/__init__.py
@@ -15,25 +15,25 @@ __diagram = contextvars.ContextVar("diagrams")
 __cluster = contextvars.ContextVar("cluster")
 
 
-def getdiagram():
+def getdiagram() -> "Diagram":
     try:
         return __diagram.get()
     except LookupError:
         return None
 
 
-def setdiagram(diagram):
+def setdiagram(diagram: "Diagram"):
     __diagram.set(diagram)
 
 
-def getcluster():
+def getcluster() -> "Cluster":
     try:
         return __cluster.get()
     except LookupError:
         return None
 
 
-def setcluster(cluster):
+def setcluster(cluster: "Cluster"):
     __cluster.set(cluster)
 
 
@@ -83,6 +83,7 @@ class Diagram:
         direction: str = "LR",
         curvestyle: str = "ortho",
         outformat: str = "png",
+        autolabel: bool = False,
         show: bool = True,
         graph_attr: dict = {},
         node_attr: dict = {},
@@ -142,6 +143,7 @@ class Diagram:
         self.dot.edge_attr.update(edge_attr)
 
         self.show = show
+        self.autolabel = autolabel
 
     def __str__(self) -> str:
         return str(self.dot)
@@ -258,11 +260,8 @@ class Cluster:
             self._diagram.subgraph(self.dot)
         setcluster(self._parent)
 
-    def _validate_direction(self, direction: str):
-        direction = direction.upper()
-        if direction in self.__directions:
-            return True
-        return False
+    def _validate_direction(self, direction: str) -> bool:
+        return direction.upper() in self.__directions
 
     def node(self, nodeid: str, label: str, **attrs) -> None:
         """Create a new node in the cluster."""
@@ -283,20 +282,32 @@ class Node:
 
     _height = 1.9
 
-    def __init__(self, label: str = "", **attrs: Dict):
+    def __init__(self, label: str = "", *, nodeid: str = None, **attrs: Dict):
         """Node represents a system component.
 
         :param label: Node label.
         """
-        # Generates an ID for identifying a node.
-        self._id = self._rand_id()
+        # Generates an ID for identifying a node, unless specified
+        self._id = nodeid or self._rand_id()
         self.label = label
 
+        # Node must be belong to a diagrams.
+        self._diagram = getdiagram()
+        if self._diagram is None:
+            raise EnvironmentError("Global diagrams context not set up")
+        
+        if self._diagram.autolabel:
+            prefix = self.__class__.__name__
+            if self.label:
+                self.label = prefix + "\n" + self.label
+            else:
+                self.label = prefix
+
         # fmt: off
         # If a node has an icon, increase the height slightly to avoid
         # that label being spanned between icon image and white space.
         # Increase the height by the number of new lines included in the label.
-        padding = 0.4 * (label.count('\n'))
+        padding = 0.4 * (self.label.count('\n'))
         self._attrs = {
             "shape": "none",
             "height": str(self._height + padding),
@@ -306,10 +317,6 @@ class Node:
         # fmt: on
         self._attrs.update(attrs)
 
-        # Node must be belong to a diagrams.
-        self._diagram = getdiagram()
-        if self._diagram is None:
-            raise EnvironmentError("Global diagrams context not set up")
         self._cluster = getcluster()
 
         # If a node is in the cluster context, add it to cluster.
diff --git a/diagrams/aws/compute.py b/diagrams/aws/compute.py
index f63c590..14c5440 100644
--- a/diagrams/aws/compute.py
+++ b/diagrams/aws/compute.py
@@ -8,6 +8,10 @@ class _Compute(_AWS):
     _icon_dir = "resources/aws/compute"
 
 
+class AppRunner(_Compute):
+    _icon = "app-runner.png"
+
+
 class ApplicationAutoScaling(_Compute):
     _icon = "application-auto-scaling.png"
 
diff --git a/diagrams/c4/__init__.py b/diagrams/c4/__init__.py
new file mode 100644
index 0000000..40577c8
--- /dev/null
+++ b/diagrams/c4/__init__.py
@@ -0,0 +1,97 @@
+"""
+A set of nodes and edges to visualize software architecture using the C4 model.
+"""
+import html
+import textwrap
+from diagrams import Cluster, Node, Edge
+
+
+def _format_node_label(name, key, description):
+    """Create a graphviz label string for a C4 node"""
+    title = f'<font point-size="12"><b>{html.escape(name)}</b></font><br/>'
+    subtitle = f'<font point-size="9">[{html.escape(key)}]<br/></font>' if key else ""
+    text = f'<br/><font point-size="10">{_format_description(description)}</font>' if description else ""
+    return f"<{title}{subtitle}{text}>"
+
+
+def _format_description(description):
+    """
+    Formats the description string so it fits into the C4 nodes.
+
+    It line-breaks the description so it fits onto exactly three lines. If there are more
+    than three lines, all further lines are discarded and "..." inserted on the last line to
+    indicate that it was shortened. This will also html-escape the description so it can
+    safely be included in a HTML label.
+    """
+    wrapper = textwrap.TextWrapper(width=40, max_lines=3)
+    lines = [html.escape(line) for line in wrapper.wrap(description)]
+    lines += [""] * (3 - len(lines))  # fill up with empty lines so it is always three
+    return "<br/>".join(lines)
+
+
+def _format_edge_label(description):
+    """Create a graphviz label string for a C4 edge"""
+    wrapper = textwrap.TextWrapper(width=24, max_lines=3)
+    lines = [html.escape(line) for line in wrapper.wrap(description)]
+    text = "<br/>".join(lines)
+    return f'<<font point-size="10">{text}</font>>'
+
+
+def C4Node(name, technology="", description="", type="Container", **kwargs):
+    key = f"{type}: {technology}" if technology else type
+    node_attributes = {
+        "label": _format_node_label(name, key, description),
+        "labelloc": "c",
+        "shape": "rect",
+        "width": "2.6",
+        "height": "1.6",
+        "fixedsize": "true",
+        "style": "filled",
+        "fillcolor": "dodgerblue3",
+        "fontcolor": "white",
+    }
+    # collapse boxes to a smaller form if they don't have a description
+    if not description:
+        node_attributes.update({"width": "2", "height": "1"})
+    node_attributes.update(kwargs)
+    return Node(**node_attributes)
+
+
+def Container(name, technology="", description="", **kwargs):
+    return C4Node(name, technology=technology, description=description, type="Container")
+
+
+def Database(name, technology="", description="", **kwargs):
+    return C4Node(name, technology=technology, description=description, type="Database", shape="cylinder", labelloc="b")
+
+
+def System(name, description="", external=False, **kwargs):
+    type = "External System" if external else "System"
+    fillcolor = "gray60" if external else "dodgerblue4"
+    return C4Node(name, description=description, type=type, fillcolor=fillcolor)
+
+
+def Person(name, description="", external=False, **kwargs):
+    type = "External Person" if external else "Person"
+    fillcolor = "gray60" if external else "dodgerblue4"
+    style = "rounded,filled"
+    return C4Node(name, description=description, type=type, fillcolor=fillcolor, style=style)
+
+
+def SystemBoundary(name, **kwargs):
+    graph_attributes = {
+        "label": html.escape(name),
+        "bgcolor": "white",
+        "margin": "16",
+        "style": "dashed",
+    }
+    graph_attributes.update(kwargs)
+    return Cluster(name, graph_attr=graph_attributes)
+
+
+def Relationship(label="", **kwargs):
+    edge_attribtues = {"style": "dashed", "color": "gray60"}
+    if label:
+        edge_attribtues.update({"label": _format_edge_label(label)})
+    edge_attribtues.update(kwargs)
+    return Edge(**edge_attribtues)
diff --git a/diagrams/custom/__init__.py b/diagrams/custom/__init__.py
index 48441a6..9845932 100644
--- a/diagrams/custom/__init__.py
+++ b/diagrams/custom/__init__.py
@@ -15,6 +15,6 @@ class Custom(Node):
     def _load_icon(self):
         return self._icon
 
-    def __init__(self, label, icon_path):
+    def __init__(self, label, icon_path, *args, **kwargs):
         self._icon = icon_path
-        super().__init__(label)
+        super().__init__(label, *args, **kwargs)
diff --git a/diagrams/generic/os.py b/diagrams/generic/os.py
index 695f295..cf0e980 100644
--- a/diagrams/generic/os.py
+++ b/diagrams/generic/os.py
@@ -16,6 +16,10 @@ class Centos(_Os):
     _icon = "centos.png"
 
 
+class Debian(_Os):
+    _icon = "debian.png"
+
+
 class IOS(_Os):
     _icon = "ios.png"
 
@@ -24,6 +28,14 @@ class LinuxGeneral(_Os):
     _icon = "linux-general.png"
 
 
+class Raspbian(_Os):
+    _icon = "raspbian.png"
+
+
+class RedHat(_Os):
+    _icon = "red-hat.png"
+
+
 class Suse(_Os):
     _icon = "suse.png"
 
diff --git a/diagrams/onprem/mlops.py b/diagrams/onprem/mlops.py
index 7678d9a..dd9fd86 100644
--- a/diagrams/onprem/mlops.py
+++ b/diagrams/onprem/mlops.py
@@ -8,6 +8,10 @@ class _Mlops(_OnPrem):
     _icon_dir = "resources/onprem/mlops"
 
 
+class Mlflow(_Mlops):
+    _icon = "mlflow.png"
+
+
 class Polyaxon(_Mlops):
     _icon = "polyaxon.png"
 
diff --git a/diagrams/onprem/registry.py b/diagrams/onprem/registry.py
new file mode 100644
index 0000000..8ee3a40
--- /dev/null
+++ b/diagrams/onprem/registry.py
@@ -0,0 +1,15 @@
+# This module is automatically generated by autogen.sh. DO NOT EDIT.
+
+from . import _OnPrem
+
+
+class _Registry(_OnPrem):
+    _type = "registry"
+    _icon_dir = "resources/onprem/registry"
+
+
+class Harbor(_Registry):
+    _icon = "harbor.png"
+
+
+# Aliases
diff --git a/diagrams/programming/framework.py b/diagrams/programming/framework.py
index 64fd639..e4ba3b6 100644
--- a/diagrams/programming/framework.py
+++ b/diagrams/programming/framework.py
@@ -36,6 +36,10 @@ class Flutter(_Framework):
     _icon = "flutter.png"
 
 
+class Graphql(_Framework):
+    _icon = "graphql.png"
+
+
 class Laravel(_Framework):
     _icon = "laravel.png"
 
@@ -67,3 +71,4 @@ class Vue(_Framework):
 # Aliases
 
 FastAPI = Fastapi
+GraphQL = Graphql
diff --git a/diagrams/saas/alerting.py b/diagrams/saas/alerting.py
index 0e3f65e..b2c2ff6 100644
--- a/diagrams/saas/alerting.py
+++ b/diagrams/saas/alerting.py
@@ -20,4 +20,8 @@ class Pushover(_Alerting):
     _icon = "pushover.png"
 
 
+class Xmatters(_Alerting):
+    _icon = "xmatters.png"
+
+
 # Aliases
diff --git a/diagrams/saas/cdn.py b/diagrams/saas/cdn.py
index 3733621..cc0b4fc 100644
--- a/diagrams/saas/cdn.py
+++ b/diagrams/saas/cdn.py
@@ -16,4 +16,8 @@ class Cloudflare(_Cdn):
     _icon = "cloudflare.png"
 
 
+class Fastly(_Cdn):
+    _icon = "fastly.png"
+
+
 # Aliases
diff --git a/diagrams/saas/chat.py b/diagrams/saas/chat.py
index e48587a..446d4c9 100644
--- a/diagrams/saas/chat.py
+++ b/diagrams/saas/chat.py
@@ -12,10 +12,18 @@ class Discord(_Chat):
     _icon = "discord.png"
 
 
+class Line(_Chat):
+    _icon = "line.png"
+
+
 class Mattermost(_Chat):
     _icon = "mattermost.png"
 
 
+class Messenger(_Chat):
+    _icon = "messenger.png"
+
+
 class RocketChat(_Chat):
     _icon = "rocket-chat.png"
 
diff --git a/diagrams/saas/communication.py b/diagrams/saas/communication.py
new file mode 100644
index 0000000..7d3a6f0
--- /dev/null
+++ b/diagrams/saas/communication.py
@@ -0,0 +1,15 @@
+# This module is automatically generated by autogen.sh. DO NOT EDIT.
+
+from . import _Saas
+
+
+class _Communication(_Saas):
+    _type = "communication"
+    _icon_dir = "resources/saas/communication"
+
+
+class Twilio(_Communication):
+    _icon = "twilio.png"
+
+
+# Aliases
diff --git a/pyproject.toml b/pyproject.toml
index 62ac57f..d43b61e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "diagrams"
-version = "0.21.1"
+version = "0.23.1"
 description = "Diagram as Code"
 license = "MIT"
 authors = ["mingrammer <mingrammer@gmail.com>"]
@@ -16,7 +16,7 @@ jinja2 = ">=2.10,<4.0"
 contextvars = { version = "^2.4", python = "~3.6" }
 
 [tool.poetry.dev-dependencies]
-pytest = "^6.2"
+pytest = "^7.0"
 pylint = "^2.7"
 black = {version = "^19.0", allow-prereleases = true}
 rope = "^0.14.0"
diff --git a/resources/.DS_Store b/resources/.DS_Store
deleted file mode 100644
index 3745356..0000000
Binary files a/resources/.DS_Store and /dev/null differ
diff --git a/resources/aws/.DS_Store b/resources/aws/.DS_Store
deleted file mode 100644
index 338fd54..0000000
Binary files a/resources/aws/.DS_Store and /dev/null differ
diff --git a/resources/aws/compute/app-runner.png b/resources/aws/compute/app-runner.png
new file mode 100644
index 0000000..c8448bc
Binary files /dev/null and b/resources/aws/compute/app-runner.png differ
diff --git a/resources/aws/management/.DS_Store b/resources/aws/management/.DS_Store
deleted file mode 100644
index 5008ddf..0000000
Binary files a/resources/aws/management/.DS_Store and /dev/null differ
diff --git a/resources/azure/.DS_Store b/resources/azure/.DS_Store
deleted file mode 100644
index 07077e3..0000000
Binary files a/resources/azure/.DS_Store and /dev/null differ
diff --git a/resources/elastic/.DS_Store b/resources/elastic/.DS_Store
deleted file mode 100644
index 1fe0117..0000000
Binary files a/resources/elastic/.DS_Store and /dev/null differ
diff --git a/resources/elastic/elasticsearch/.DS_Store b/resources/elastic/elasticsearch/.DS_Store
deleted file mode 100644
index 9d4b6d7..0000000
Binary files a/resources/elastic/elasticsearch/.DS_Store and /dev/null differ
diff --git a/resources/generic/.DS_Store b/resources/generic/.DS_Store
deleted file mode 100644
index 3778fc4..0000000
Binary files a/resources/generic/.DS_Store and /dev/null differ
diff --git a/resources/generic/os/debian.png b/resources/generic/os/debian.png
new file mode 100644
index 0000000..5bd5edc
Binary files /dev/null and b/resources/generic/os/debian.png differ
diff --git a/resources/generic/os/raspbian.png b/resources/generic/os/raspbian.png
new file mode 100644
index 0000000..b93c4c6
Binary files /dev/null and b/resources/generic/os/raspbian.png differ
diff --git a/resources/generic/os/red-hat.png b/resources/generic/os/red-hat.png
new file mode 100644
index 0000000..4890181
Binary files /dev/null and b/resources/generic/os/red-hat.png differ
diff --git a/resources/oci/.DS_Store b/resources/oci/.DS_Store
deleted file mode 100644
index c6b012d..0000000
Binary files a/resources/oci/.DS_Store and /dev/null differ
diff --git a/resources/onprem/.DS_Store b/resources/onprem/.DS_Store
deleted file mode 100644
index e64cf1c..0000000
Binary files a/resources/onprem/.DS_Store and /dev/null differ
diff --git a/resources/onprem/analytics/dremio.png b/resources/onprem/analytics/dremio.png
index ce3ba2c..ba4c8b1 100644
Binary files a/resources/onprem/analytics/dremio.png and b/resources/onprem/analytics/dremio.png differ
diff --git a/resources/onprem/database/.DS_Store b/resources/onprem/database/.DS_Store
deleted file mode 100644
index 5008ddf..0000000
Binary files a/resources/onprem/database/.DS_Store and /dev/null differ
diff --git a/resources/onprem/mlops/mlflow.png b/resources/onprem/mlops/mlflow.png
new file mode 100644
index 0000000..3af24ab
Binary files /dev/null and b/resources/onprem/mlops/mlflow.png differ
diff --git a/resources/onprem/network/glassfish.png b/resources/onprem/network/glassfish.png
index a94d2dd..a8d2d77 100644
Binary files a/resources/onprem/network/glassfish.png and b/resources/onprem/network/glassfish.png differ
diff --git a/resources/onprem/network/gunicorn.png b/resources/onprem/network/gunicorn.png
index 6d277e0..1af455e 100644
Binary files a/resources/onprem/network/gunicorn.png and b/resources/onprem/network/gunicorn.png differ
diff --git a/resources/onprem/network/ocelot.png b/resources/onprem/network/ocelot.png
index 1216057..9994316 100644
Binary files a/resources/onprem/network/ocelot.png and b/resources/onprem/network/ocelot.png differ
diff --git a/resources/onprem/network/powerdns.png b/resources/onprem/network/powerdns.png
index 491c66c..5c17770 100644
Binary files a/resources/onprem/network/powerdns.png and b/resources/onprem/network/powerdns.png differ
diff --git a/resources/onprem/registry/harbor.png b/resources/onprem/registry/harbor.png
new file mode 100644
index 0000000..4f2c909
Binary files /dev/null and b/resources/onprem/registry/harbor.png differ
diff --git a/resources/programming/framework/graphql.png b/resources/programming/framework/graphql.png
new file mode 100644
index 0000000..fe9e52d
Binary files /dev/null and b/resources/programming/framework/graphql.png differ
diff --git a/resources/saas/alerting/xmatters.png b/resources/saas/alerting/xmatters.png
new file mode 100644
index 0000000..60363c3
Binary files /dev/null and b/resources/saas/alerting/xmatters.png differ
diff --git a/resources/saas/cdn/fastly.png b/resources/saas/cdn/fastly.png
new file mode 100644
index 0000000..6fffd67
Binary files /dev/null and b/resources/saas/cdn/fastly.png differ
diff --git a/resources/saas/chat/line.png b/resources/saas/chat/line.png
new file mode 100644
index 0000000..ef77de1
Binary files /dev/null and b/resources/saas/chat/line.png differ
diff --git a/resources/saas/chat/messenger.png b/resources/saas/chat/messenger.png
new file mode 100644
index 0000000..0dd9e89
Binary files /dev/null and b/resources/saas/chat/messenger.png differ
diff --git a/resources/saas/communication/twilio.png b/resources/saas/communication/twilio.png
new file mode 100644
index 0000000..86cbbf5
Binary files /dev/null and b/resources/saas/communication/twilio.png differ
diff --git a/setup.py b/setup.py
index 1c9b5de..d78c278 100644
--- a/setup.py
+++ b/setup.py
@@ -7,6 +7,7 @@ packages = \
  'diagrams.aws',
  'diagrams.azure',
  'diagrams.base',
+ 'diagrams.c4',
  'diagrams.custom',
  'diagrams.digitalocean',
  'diagrams.elastic',
@@ -33,13 +34,13 @@ extras_require = \
 
 setup_kwargs = {
     'name': 'diagrams',
-    'version': '0.21.1',
+    'version': '0.23.1',
     'description': 'Diagram as Code',
-    'long_description': '![diagrams logo](assets/img/diagrams.png)\n\n# Diagrams\n\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE)\n[![pypi version](https://badge.fury.io/py/diagrams.svg)](https://badge.fury.io/py/diagrams)\n![python version](https://img.shields.io/badge/python-%3E%3D%203.6-blue?logo=python)\n![Run tests](https://github.com/mingrammer/diagrams/workflows/Run%20tests/badge.svg?branch=master)\n[![todos](https://badgen.net/https/api.tickgit.com/badgen/github.com/mingrammer/diagrams?label=todos)](https://www.tickgit.com/browse?repo=github.com/mingrammer/diagrams)\n![contributors](https://img.shields.io/github/contributors/mingrammer/diagrams)\n\n<a href="https://www.buymeacoffee.com/mingrammer" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>\n\n**Diagram as Code**.\n\nDiagrams lets you draw the cloud system architecture **in Python code**. It was born for **prototyping** a new system architecture design without any design tools. You can also describe or visualize the existing system architecture as well. Diagrams currently supports main major providers including: `AWS`, `Azure`, `GCP`, `Kubernetes`, `Alibaba Cloud`, `Oracle Cloud` etc... It also supports `On-Premise` nodes, `SaaS` and major `Programming` frameworks and languages.\n\n**Diagram as Code** also allows you to **track** the architecture diagram changes in any **version control** system.\n\n>  NOTE: It does not control any actual cloud resources nor does it generate cloud formation or terraform code. It is just for drawing the cloud system architecture diagrams.\n\n## Providers\n\n![aws provider](https://img.shields.io/badge/AWS-orange?logo=amazon-aws&color=ff9900)\n![azure provider](https://img.shields.io/badge/Azure-orange?logo=microsoft-azure&color=0089d6)\n![gcp provider](https://img.shields.io/badge/GCP-orange?logo=google-cloud&color=4285f4)\n![ibm provider](https://img.shields.io/badge/IBM-orange?logo=ibm&color=052FAD)\n![kubernetes provider](https://img.shields.io/badge/Kubernetes-orange?logo=kubernetes&color=326ce5)\n![alibaba cloud provider](https://img.shields.io/badge/AlibabaCloud-orange?logo=alibaba-cloud&color=ff6a00)\n![oracle cloud provider](https://img.shields.io/badge/OracleCloud-orange?logo=oracle&color=f80000)\n![openstack provider](https://img.shields.io/badge/OpenStack-orange?logo=openstack&color=da1a32)\n![firebase provider](https://img.shields.io/badge/Firebase-orange?logo=firebase&color=FFCA28)\n![digital ocean provider](https://img.shields.io/badge/DigitalOcean-0080ff?logo=digitalocean&color=0080ff)\n![elastic provider](https://img.shields.io/badge/Elastic-orange?logo=elastic&color=005571)\n![outscale provider](https://img.shields.io/badge/OutScale-orange?color=5f87bf)\n![on premise provider](https://img.shields.io/badge/OnPremise-orange?color=5f87bf)\n![generic provider](https://img.shields.io/badge/Generic-orange?color=5f87bf)\n![programming provider](https://img.shields.io/badge/Programming-orange?color=5f87bf)\n![saas provider](https://img.shields.io/badge/SaaS-orange?color=5f87bf)\n\n## Getting Started\n\nIt requires **Python 3.6** or higher, check your Python version first.\n\nIt uses [Graphviz](https://www.graphviz.org/) to render the diagram, so you need to [install Graphviz](https://graphviz.gitlab.io/download/) to use **diagrams**. After installing graphviz (or already have it), install the **diagrams**.\n\n> macOS users can download the Graphviz via `brew install graphviz` if you\'re using [Homebrew](https://brew.sh).\n\n```shell\n# using pip (pip3)\n$ pip install diagrams\n\n# using pipenv\n$ pipenv install diagrams\n\n# using poetry\n$ poetry add diagrams\n```\n\nYou can start with [quick start](https://diagrams.mingrammer.com/docs/getting-started/installation#quick-start). Check out [guides](https://diagrams.mingrammer.com/docs/guides/diagram) for more details, and you can find all available nodes list in [here](https://diagrams.mingrammer.com/docs/nodes/aws).\n\n## Examples\n\n| Event Processing                                             | Stateful Architecture                                        | Advanced Web Service                                         |\n| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| ![event processing](https://diagrams.mingrammer.com/img/event_processing_diagram.png) | ![stateful architecture](https://diagrams.mingrammer.com/img/stateful_architecture_diagram.png) | ![advanced web service with on-premise](https://diagrams.mingrammer.com/img/advanced_web_service_with_on-premise.png) |\n\nYou can find all the examples on the [examples](https://diagrams.mingrammer.com/docs/getting-started/examples) page.\n\n## Contributing\n\nTo contribute to diagram, check out [contribution guidelines](CONTRIBUTING.md).\n\n> Let me know if you are using diagrams! I\'ll add you in showcase page. (I\'m working on it!) :)\n\n## Who uses it?\n\n[GitPitch](https://gitpitch.github.io/gitpitch) is the perfect slide deck solution for Tech Conferences, Training, Developer Advocates, and Educators. Diagrams is now available as a dedicated [Cloud Diagram Markdown Widget](https://gitpitch.github.io/gitpitch/#/diagrams/cloud-architecture) so you can use Diagrams directly on any slide for conferences, meetups, and training.\n\n[Cloudiscovery](https://github.com/Cloud-Architects/cloudiscovery) helps you to analyze resources in your cloud (AWS/GCP/Azure/Alibaba/IBM) account. It allows you to create a diagram of analyzed cloud resource map based on this Diagrams library, so you can draw your existing cloud infrastructure with Cloudiscovery.\n\n[Airflow Diagrams](https://github.com/feluelle/airflow-diagrams) is an Airflow plugin that aims to easily visualise your Airflow DAGs on service level from providers like AWS, GCP, Azure, etc. via diagrams.\n\n## Other languages\n\n- If you are familiar to Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.\n\n## License\n\n[MIT](LICENSE)\n',
+    'long_description': '![diagrams logo](assets/img/diagrams.png)\n\n# Diagrams\n\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE)\n[![pypi version](https://badge.fury.io/py/diagrams.svg)](https://badge.fury.io/py/diagrams)\n![python version](https://img.shields.io/badge/python-%3E%3D%203.6-blue?logo=python)\n![Run tests](https://github.com/mingrammer/diagrams/workflows/Run%20tests/badge.svg?branch=master)\n[![todos](https://badgen.net/https/api.tickgit.com/badgen/github.com/mingrammer/diagrams?label=todos)](https://www.tickgit.com/browse?repo=github.com/mingrammer/diagrams)\n![contributors](https://img.shields.io/github/contributors/mingrammer/diagrams)\n\n<a href="https://www.buymeacoffee.com/mingrammer" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>\n\n**Diagram as Code**.\n\nDiagrams lets you draw the cloud system architecture **in Python code**. It was born for **prototyping** a new system architecture design without any design tools. You can also describe or visualize the existing system architecture as well. Diagrams currently supports main major providers including: `AWS`, `Azure`, `GCP`, `Kubernetes`, `Alibaba Cloud`, `Oracle Cloud` etc... It also supports `On-Premise` nodes, `SaaS` and major `Programming` frameworks and languages.\n\n**Diagram as Code** also allows you to **track** the architecture diagram changes in any **version control** system.\n\n>  NOTE: It does not control any actual cloud resources nor does it generate cloud formation or terraform code. It is just for drawing the cloud system architecture diagrams.\n\n## Providers\n\n![aws provider](https://img.shields.io/badge/AWS-orange?logo=amazon-aws&color=ff9900)\n![azure provider](https://img.shields.io/badge/Azure-orange?logo=microsoft-azure&color=0089d6)\n![gcp provider](https://img.shields.io/badge/GCP-orange?logo=google-cloud&color=4285f4)\n![ibm provider](https://img.shields.io/badge/IBM-orange?logo=ibm&color=052FAD)\n![kubernetes provider](https://img.shields.io/badge/Kubernetes-orange?logo=kubernetes&color=326ce5)\n![alibaba cloud provider](https://img.shields.io/badge/AlibabaCloud-orange?logo=alibaba-cloud&color=ff6a00)\n![oracle cloud provider](https://img.shields.io/badge/OracleCloud-orange?logo=oracle&color=f80000)\n![openstack provider](https://img.shields.io/badge/OpenStack-orange?logo=openstack&color=da1a32)\n![firebase provider](https://img.shields.io/badge/Firebase-orange?logo=firebase&color=FFCA28)\n![digital ocean provider](https://img.shields.io/badge/DigitalOcean-0080ff?logo=digitalocean&color=0080ff)\n![elastic provider](https://img.shields.io/badge/Elastic-orange?logo=elastic&color=005571)\n![outscale provider](https://img.shields.io/badge/OutScale-orange?color=5f87bf)\n![on premise provider](https://img.shields.io/badge/OnPremise-orange?color=5f87bf)\n![generic provider](https://img.shields.io/badge/Generic-orange?color=5f87bf)\n![programming provider](https://img.shields.io/badge/Programming-orange?color=5f87bf)\n![saas provider](https://img.shields.io/badge/SaaS-orange?color=5f87bf)\n![c4 provider](https://img.shields.io/badge/C4-orange?color=5f87bf)\n\n## Getting Started\n\nIt requires **Python 3.6** or higher, check your Python version first.\n\nIt uses [Graphviz](https://www.graphviz.org/) to render the diagram, so you need to [install Graphviz](https://graphviz.gitlab.io/download/) to use **diagrams**. After installing graphviz (or already have it), install the **diagrams**.\n\n> macOS users can download the Graphviz via `brew install graphviz` if you\'re using [Homebrew](https://brew.sh).\n\n```shell\n# using pip (pip3)\n$ pip install diagrams\n\n# using pipenv\n$ pipenv install diagrams\n\n# using poetry\n$ poetry add diagrams\n```\n\nYou can start with [quick start](https://diagrams.mingrammer.com/docs/getting-started/installation#quick-start). Check out [guides](https://diagrams.mingrammer.com/docs/guides/diagram) for more details, and you can find all available nodes list in [here](https://diagrams.mingrammer.com/docs/nodes/aws).\n\n## Examples\n\n| Event Processing                                             | Stateful Architecture                                        | Advanced Web Service                                         |\n| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| ![event processing](https://diagrams.mingrammer.com/img/event_processing_diagram.png) | ![stateful architecture](https://diagrams.mingrammer.com/img/stateful_architecture_diagram.png) | ![advanced web service with on-premise](https://diagrams.mingrammer.com/img/advanced_web_service_with_on-premise.png) |\n\nYou can find all the examples on the [examples](https://diagrams.mingrammer.com/docs/getting-started/examples) page.\n\n## Contributing\n\nTo contribute to diagram, check out [contribution guidelines](CONTRIBUTING.md).\n\n> Let me know if you are using diagrams! I\'ll add you in showcase page. (I\'m working on it!) :)\n\n## Who uses it?\n\n[GitPitch](https://gitpitch.github.io/gitpitch) is the perfect slide deck solution for Tech Conferences, Training, Developer Advocates, and Educators. Diagrams is now available as a dedicated [Cloud Diagram Markdown Widget](https://gitpitch.github.io/gitpitch/#/diagrams/cloud-architecture) so you can use Diagrams directly on any slide for conferences, meetups, and training.\n\n[Cloudiscovery](https://github.com/Cloud-Architects/cloudiscovery) helps you to analyze resources in your cloud (AWS/GCP/Azure/Alibaba/IBM) account. It allows you to create a diagram of analyzed cloud resource map based on this Diagrams library, so you can draw your existing cloud infrastructure with Cloudiscovery.\n\n[Airflow Diagrams](https://github.com/feluelle/airflow-diagrams) is an Airflow plugin that aims to easily visualise your Airflow DAGs on service level from providers like AWS, GCP, Azure, etc. via diagrams.\n\n## Other languages\n\n- If you are familiar with Go, you can use [go-diagrams](https://github.com/blushft/go-diagrams) as well.\n\n## License\n\n[MIT](LICENSE)\n',
     'author': 'mingrammer',
     'author_email': 'mingrammer@gmail.com',
-    'maintainer': None,
-    'maintainer_email': None,
+    'maintainer': 'None',
+    'maintainer_email': 'None',
     'url': 'https://diagrams.mingrammer.com',
     'packages': packages,
     'package_data': package_data,

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.23.1.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.23.1.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.23.1.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.23.1.egg-info/top_level.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams/c4/__init__.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams/onprem/registry.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams/saas/communication.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/aws/compute/app-runner.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/generic/os/debian.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/generic/os/raspbian.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/generic/os/red-hat.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/onprem/mlops/mlflow.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/onprem/registry/harbor.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/programming/framework/graphql.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/saas/alerting/xmatters.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/saas/cdn/fastly.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/saas/chat/line.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/saas/chat/messenger.png
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/resources/saas/communication/twilio.png

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.21.1.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.21.1.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.21.1.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/diagrams-0.21.1.egg-info/top_level.txt

No differences were encountered in the control files

More details

Full run details