|
| 1 | +Generate Plantuml diagrams to document your python code |
| 2 | + |
| 3 | +# How it works |
| 4 | + |
| 5 | +From a given path corresponding to a folder containing python code, `py2puml` loads each file as a module and generate a class diagram with the [PlantUML](https://plantuml.com/en/class-diagram) using: |
| 6 | + |
| 7 | +* inspection to detect the classes to document (see the [inspect](https://docs.python.org/3/library/inspect.html) module) |
| 8 | +* annotations (the python type hinting syntax) to detect the attributes and their types (see the [typing](https://docs.python.org/3/library/typing.html) module) |
| 9 | + |
| 10 | +Current limitations: |
| 11 | + |
| 12 | +* type hinting is optional when writing the code and discarded when it is executed, as mentionned in the official documentation. The quality of the diagram output by `py2puml` depends on the reliability with which the annotations were written |
| 13 | + |
| 14 | +> The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc. |
| 15 | +
|
| 16 | +* complex type hints with more than one level of genericity are not properly handled for the moment: `List[MyClass]` or `Dict[str, MyClass]` are handled properly, `Dict[str, List[MyClass]]` is not. If your domain classes (also called business objects or DTOs) have attributes with complex type hints, it may be a code smell indicating that you should write a class which would better represent the business logic. But I may improve this part of the library as well 😀 |
| 17 | + |
| 18 | +* composition relationships are detected and drawn. Inheritance relationships are not handled for now |
| 19 | + |
| 20 | +* `py2puml` does not inspect sub-folders recursively, but it is planned |
| 21 | + |
| 22 | +* `py2puml` outputs diagrams in PlantUML syntax, which can be saved in text files along your python code and versioned with them. To generate image files, use the PlantUML runtime or a docker image (see [think/plantuml](https://hub.docker.com/r/think/plantuml)) |
| 23 | + |
| 24 | +* `py2puml` uses features of python 3 (generators for example) and thus won't work with python 2 runtimes. It relies on native python modules and uses no 3rd-party library, except [pytest](https://docs.pytest.org/en/latest/) as a development dependency for running the unit-tests |
| 25 | + |
| 26 | +You may also be interested in this [lucsorel/plantuml-file-loader](https://github.com/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](https://github.com/lucsorel/markdown-image-loader/blob/master/README.md#web-based-slideshows) with RevealJS or RemarkJS). |
| 27 | + |
| 28 | +# Install |
| 29 | + |
| 30 | +Install from the github repository: |
| 31 | + |
| 32 | +* with `pip`: |
| 33 | + |
| 34 | +```sh |
| 35 | +pip3 install git+https://github.com/lucsorel/py2puml.git |
| 36 | +``` |
| 37 | + |
| 38 | +* with [poetry](https://pipenv.readthedocs.io/en/latest/): |
| 39 | + |
| 40 | +```sh |
| 41 | +poetry add git+https://github.com/lucsorel/py2puml.git |
| 42 | +``` |
| 43 | + |
| 44 | +* with [pipenv](https://pipenv.readthedocs.io/en/latest/): |
| 45 | + |
| 46 | +```sh |
| 47 | +# should be installed in editable mode to ensure an up-to-date copy of the repository and that it includes all known dependencies -> '-e' |
| 48 | +pipenv install -e git+https://github.com/lucsorel/py2puml.git#egg=py2puml |
| 49 | +``` |
| 50 | + |
| 51 | +# Usage |
| 52 | + |
| 53 | +For example, to create the diagram of the classes used by `py2puml`: |
| 54 | + |
| 55 | +* import the py2puml function in your script (see [py2puml/example.py](py2puml/example.py)): |
| 56 | + |
| 57 | +```python |
| 58 | +from py2puml.py2puml import py2puml |
| 59 | + |
| 60 | +# outputs the PlantUML content in the terminal |
| 61 | +print(''.join(py2puml('py2puml/domain', 'py2puml.domain'))) |
| 62 | + |
| 63 | +# writes the PlantUML content in a file |
| 64 | +with open('py2puml/domain.puml', 'w') as puml_file: |
| 65 | + puml_file.writelines(py2puml('py2puml/domain', 'py2puml.domain')) |
| 66 | +``` |
| 67 | + |
| 68 | +* running it (`python3 -m py2puml.example`) will output the PlantUML diagram in the terminal and write it in a file |
| 69 | + |
| 70 | +```plantuml |
| 71 | +@startuml |
| 72 | +class py2puml.domain.umlattribute.UmlAttribute { |
| 73 | + name: str |
| 74 | + type: str |
| 75 | +} |
| 76 | +class py2puml.domain.umlclass.UmlClass { |
| 77 | + name: str |
| 78 | + fqdn: str |
| 79 | + attributes: List[UmlAttribute] |
| 80 | +} |
| 81 | +class py2puml.domain.umlcomposition.UmlComposition { |
| 82 | + compound_fqdn: str |
| 83 | + component_fqdn: str |
| 84 | +} |
| 85 | +py2puml.domain.umlclass.UmlClass *-- py2puml.domain.umlattribute.UmlAttribute |
| 86 | +@enduml |
| 87 | +``` |
| 88 | + |
| 89 | +# Tests |
| 90 | + |
| 91 | +```sh |
| 92 | +poetry run python3 -W ignore::DeprecationWarning -m pytest -v |
| 93 | +``` |
| 94 | + |
| 95 | +# Licence |
| 96 | + |
| 97 | +Unless stated otherwise all works are licensed under the [MIT license](http://spdx.org/licenses/MIT.html), a copy of which is included [here](LICENSE). |
| 98 | + |
| 99 | +# Contributions |
| 100 | + |
| 101 | +* [Luc Sorel-Giffo](https://github.com/lucsorel) |
| 102 | + |
| 103 | +Pull-requests are welcome and will be processed on a best-effort basis. |
| 104 | + |
| 105 | + |
| 106 | +# Alternatives |
| 107 | + |
| 108 | +If `py2uml` 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): |
| 109 | + |
| 110 | +* [cb109/pyplantuml](https://github.com/cb109/pyplantuml) |
| 111 | +* [deadbok/py-puml-tools](https://github.com/deadbok/py-puml-tools) |
| 112 | +* [caballero/genUML](https://github.com/jose-caballero/genUML) |
0 commit comments