lucsorel / py2puml

Generate PlantUML class diagrams to document your Python application.
https://pypi.org/project/py2puml/
MIT License
225 stars 35 forks source link
annotations ast class-diagram documentation plantuml python python3 type-hints
Python logo PlantUML logo

Python to PlantUML

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.

How it works

py2puml produces a class diagram PlantUML script representing classes properties (static and instance attributes) and their relations (composition and inheritance relationships).

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

Minimum Python versions to run py2puml

p2puml uses some code-parsing features that are available only since Python 3.8 (like ast.get_source_segment). If your codebase uses the int | float syntax to define optional types, then you should use Python 3.10 to run py2puml.

To sum it up, use at least Python 3.8 to run py2puml, or a higher version if you use syntax features available only in higher versions.

The .python-version file indicates the Python version used to develop the library. It is a file used by pyenv to define the binary used by the project.

Features

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

py2puml outputs diagrams in PlantUML syntax, which can be:

To generate image files, use the PlantUML runtime, a docker image of the runtime (see think/plantuml) or of a server (see the CLI documentation below)

If you like tools related with PlantUML, you may also be interested in this lucsorel/plantuml-file-loader project: a webpack loader which converts PlantUML files into images during the webpack processing (useful to include PlantUML diagrams in your slides with RevealJS or RemarkJS).

Install

Install from PyPI:

pip install py2puml
poetry add py2puml
pipenv install py2puml

Usage

CLI

Once py2puml is installed at the system level, an eponymous command is available in your environment shell.

For example, to create the diagram of the classes used by py2puml, run:

py2puml py2puml/domain py2puml.domain

This outputs the following PlantUML content:

@startuml py2puml.domain
!pragma useIntermediatePackages false

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.umlitem.UmlItem {
  name: str
  fqn: str
}
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}
}
class py2puml.domain.umlrelation.UmlRelation {
  source_fqn: str
  target_fqn: str
  type: 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
py2puml.domain.umlrelation.UmlRelation *-- py2puml.domain.umlrelation.RelType
footer Generated by //py2puml//
@enduml

Using PlantUML, this content is rendered as in this diagram:

py2puml domain UML Diagram

For a full overview of the CLI, run:

py2puml --help

The CLI can also be launched as a python module:

python -m py2puml py2puml/domain py2puml.domain

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 py2puml/domain py2puml.domain | curl -X POST --data-binary @- http://localhost:1234/svg/ --output - | display

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

Python API

For example, to create the diagram of the domain classes used by py2puml:

from py2puml.py2puml import py2puml

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

    # 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'))

Tests

# directly with poetry
poetry run pytest -v

# in a virtual environment
python3 -m pytest -v

Code coverage (with missed branch statements):

poetry run pytest -v --cov=py2puml --cov-branch --cov-report term-missing --cov-fail-under 93

Changelog

Licence

Unless stated otherwise all works are licensed under the MIT license, a copy of which is included here.

Contributions

Pull requests

Pull-requests are welcome and will be processed on a best-effort basis.

Pull requests must follow the guidelines enforced by the pre-commit hooks:

Please also follow the contributing guide to ease your contribution.

Code conventions

The code conventions are described and enforced by pre-commit hooks to maintain consistency across the code base. The hooks are declared in the .pre-commit-config.yaml file.

Set the git hooks (pre-commit and commit-msg types):

poetry run pre-commit install --hook-type pre-commit --hook-type commit-msg

Before committing, you can check your changes with:

# put all your changes in the git staging area
git add -A

# all hooks
poetry run pre-commit run --all-files

# a specific hook
poetry run pre-commit run ruff --all-files

Commit messages

Please, follow the conventions of the Angular team for commit messages. When merging your pull-request, the new version of the project will be derived from the messages.

Code formatting

This project uses isort and ruff-format to format the code. The guidelines are expressed in their respective sections in the pyproject.toml file.

Best practices

This project uses the ruff linter, which is configured in its section in the pyproject.toml file.

Current limitations

Alternatives

If py2puml does not meet your needs (suggestions and pull-requests are welcome), you can have a look at these projects which follow other approaches (AST, linting, modeling):