SkillAgentSearch skills...

Py2puml

Generate PlantUML class diagrams to document your Python application.

Install / Use

/learn @lucsorel/Py2puml
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center"> <a href="https://www.python.org/psf-landing/" target="_blank"> <img width="350px" alt="Python logo" src="https://www.python.org/static/community_logos/python-logo-generic.svg" /> </a> <a href="https://plantuml.com/" target="_blank"> <img width="116px" height="112px" alt="PlantUML logo" src="https://cdn-0.plantuml.com/logoc.png" style="margin-bottom: 40px" vspace="40px" /> </a> <h1>Python to PlantUML</h1> </div>

Generate PlantUML class diagrams to document your Python application.

pre-commit.ci status

py2puml uses pre-commit hooks and pre-commit.ci Continuous Integration to enforce commit messages, code formatting and linting for quality and consistency sake. See the code conventions section if you would like to contribute to the project.

Installation

py2puml is a command-line interface (CLI) documentation tool that can be installed as a dependency of your project, or installed globally on your system, or even run in an isolated way.

Install as a project dependency

Install py2puml from PyPI with your favorite installation tool:

pip install py2puml

uv add py2puml

poetry add py2puml

pipenv install py2puml

Run as an isolated binary

Uv can download and install py2puml on your system and run it in an isolated way (no influence on your other Python tools):

uvx --isolated py2puml --help

Usage

The primary purpose of py2puml is to document domain models as PlantUML class diagrams, it focuses on data structures attributes and relationships (inheritance and composition/association). Documenting methods may come later.

Once py2puml is installed, an eponymous CLI is available in your environment shell.

Generate documentation in the standard output

Give py2puml a package (a folder) or a module (a .py file) to inspect and it will generate the PlantUML diagram either in the standard output or in a file path:

To document the domain model used by py2puml to model data structures:

# at the root of the py2puml project
py2puml --path py2puml/domain
# short-flag version:
py2puml -p py2puml/domain

This outputs the following PlantUML content:

@startuml py2puml.domain
!pragma useIntermediatePackages false

class py2puml.domain.umlitem.UmlItem {
  name: str
  fqn: str
}
class py2puml.domain.umlrelation.UmlRelation {
  source_fqn: str
  target_fqn: str
  type: RelType
}
class py2puml.domain.inspection.Inspection {
  items_by_fqn: Any
  relations: Any
}
class py2puml.domain.umlclass.UmlAttribute {
  name: str
  type: str
  static: bool
}
class py2puml.domain.umlclass.UmlClass {
  attributes: List[UmlAttribute]
  is_abstract: bool
}
class py2puml.domain.umlenum.Member {
  name: str
  value: str
}
class py2puml.domain.umlenum.UmlEnum {
  members: List[Member]
}
enum py2puml.domain.umlrelation.RelType {
  COMPOSITION: * {static}
  INHERITANCE: <| {static}
}
py2puml.domain.umlrelation.UmlRelation *-- py2puml.domain.umlrelation.RelType
py2puml.domain.umlclass.UmlClass *-- py2puml.domain.umlclass.UmlAttribute
py2puml.domain.umlitem.UmlItem <|-- py2puml.domain.umlclass.UmlClass
py2puml.domain.umlenum.UmlEnum *-- py2puml.domain.umlenum.Member
py2puml.domain.umlitem.UmlItem <|-- py2puml.domain.umlenum.UmlEnum
footer Generated by //py2puml//
@enduml

Using PlantUML (online or with IDE extensions) renders this content as follows:

py2puml domain UML Diagram

Pipe the diagram in a local PlantUML server

Pipe the result of the CLI with a PlantUML server for instantaneous documentation (rendered by ImageMagick):

# runs a local PlantUML server from a docker container:
docker run -d --rm -p 1234:8080 --name plantumlserver plantuml/plantuml-server:jetty

py2puml -p py2puml/domain | curl -X POST --data-binary @- http://localhost:1234/svg/ --output - | display

# stop the container when you don't need it anymore, restart it later
docker stop plantumlserver
docker start plantumlserver

Generate documentation in a file

py2puml --path py2puml/domain --output-file py2puml-domain.puml
# short-flag version:
py2puml -p py2puml/domain -o py2puml-domain.puml

Generate documentation for a specific module

py2puml --path py2puml/domain/umlitem.py
@startuml py2puml.domain.umlitem
!pragma useIntermediatePackages false

class py2puml.domain.umlitem.UmlItem {
  name: str
  fqn: str
}
footer Generated by //py2puml//
@enduml

Generate documentation for a project with a src folder

Use the --path flag to indicate the path to the root namespace of the project and the --namespace flag to indicate that the "src" part should be ignored:

py2puml -p src/project -n project

Note: py2puml won't handle automatically the "src" part if it is in the middle of the path to inspect.

Use py2puml outside the namespace root

By default, py2puml derives the Python namespace from the given path, assuming the command is called from the root namespace:

py2puml --path py2puml/domain
# is equivalent to:
py2puml --path py2puml/domain --namespace py2puml.domain
# short-flag version
py2puml -p py2puml/domain -n py2puml.domain

But sometimes your shell may be positionned out of the namespace folder, or within it. In such cases, it is necessary to specify the namespace of the domain to inspect so that py2puml can inspect it properly and follow the imports in the inspected package or modules:

# from your home folder:
# - for a package
py2puml --path repositories/py2puml/py2puml/domain --namespace py2puml.domain
# -> py2puml will move down its "inspection working directory" to repositories/py2puml

# - for a module
py2puml -p repositories/py2puml/py2puml/domain/item.py -n py2puml.domain.umlitem

# from a sub-package of the project to inspect (in py2puml/domain)
# - for a package
py2puml --path . --namespace py2puml.domain
# -> py2puml will move its "inspection working directory" up 2 folders in order to be at the root namespace
# - for a module
py2puml -p umlitem.py -n py2puml.domain.umlitem

Help commands

For a full overview of the CLI, run:

# documents the available flags and their description
py2puml --help

# displays the installed version
py2puml --version
# -> py2puml 0.11.0

Python API

To programatically create the diagram of the py2puml domain classes, import the py2puml function in your script:

from py2puml.py2puml import py2puml

if __name__ == '__main__':
    # 1. outputs the PlantUML content in the terminal
    print(''.join(py2puml('py2puml/domain', 'py2puml.domain')))

    # 2. or writes the PlantUML content in a file
    with open('py2puml/py2puml.domain.puml', 'w', encoding='utf8') as puml_file:
        puml_file.writelines(py2puml('py2puml/domain', 'py2puml.domain'))

How it works

py2puml internally uses code inspection (also called reflexion in other programming languages) and abstract tree parsing to retrieve relevant information.

Features

From a given path corresponding to a folder containing Python code, py2puml inspects each Python module and generates a PlantUML diagram from the definitions of various data structures using:

  • inspection and type annotations to detect:

    • static class attributes and dataclass fields
    • fields of namedtuples
    • members of enumerations
    • composition and inheritance relationships. The detection of composition relationships relies on type annotations only, assigned values or expressions are never evaluated to prevent unwanted side-effects
  • parsing abstract syntax trees to detect the instance attributes defined in __init__ constructors

py2puml outputs diagrams in PlantUML syntax, which can be:

from py2puml.asserts import assert_py2puml_command_args

def test_assert_domain_documentation():
    assert_py2puml_command_args('-p py2puml/domain', DOCUMENTATION_PATH / 'py2puml.domain.puml')
    # temporarily add the `overwrite_expected_output=True` argument to update the file containing the expected contents
    assert_py2puml_command_args('-p py2puml/domain', DOCUMENTATION_PATH / 'py2puml.domain.puml', overwrite_expected_output=True)
  • generated and hosted along other code documentation (better option: generated documentation should not be versioned with the codebase

Related Skills

View on GitHub
GitHub Stars271
CategoryDevelopment
Updated4d ago
Forks41

Languages

Python

Security Score

100/100

Audited on Mar 30, 2026

No findings