py2puml icon indicating copy to clipboard operation
py2puml copied to clipboard

Newbie question: how to run py2puml in certain hiearchy?

Open Highlander1970 opened this issue 2 years ago • 12 comments

I humbly apologize for an absolute newbie question, but I seem to be unable to get py2puml to produce any usable result (apart from empty "@startuml/@enduml"):

As a work in progress, I have following file structure: C:\Folder_A\Folder_AA\Folder_Project\module1.py C:\Folder_A\Folder_AA\Folder_Project\module2.py C:\Folder_A\Folder_AA\Folder_Project\subfolder\module3.py

What am I to enter into path and module parameters to get an output of all classes used in all three modules?

Highlander1970 avatar Oct 24 '21 10:10 Highlander1970

Hello @Highlander1970, any questions are ok to ask :smiley:

Given the folder names you gave as an example, I assume the Folder_Project is the root module of your Python application. This implies that:

  • there should be a C:\Folder_A\Folder_AA\pyproject.toml or C:\Folder_A\Folder_AA\requirements.txt file defining respectively the Folder_Project python project or its dependencies, if need be (see 'That's right...our Python code files actually belong in a separate subdirectory!' in https://dev.to/codemouse92/dead-simple-python-project-structure-and-imports-38c6#setting-up-the-repository)
  • similarly, if you have unit tests, they should be located in a C:\Folder_A\Folder_AA\tests folder

Assuming that you either have installed py2puml as a project dependency or at the system level, you should type in a terminal the following commands:

cd C:\Folder_A\Folder_AA

py2puml Folder_Project Folder_Project

Do these commands output what you expect?

lucsorel avatar Oct 24 '21 13:10 lucsorel

I am so confused too. The root of my Python project is the root of my git repo (the repo I'm looking doesn't do a deeper hierarchy than that).

No matter what I do I either get empty UML or I get a No module named 'xxx'.

Can you give an example for this use case? Perhaps, there needs some verbose output in these cases to explain how the parameters are interpreted and how the resolution is done.

huyz avatar Oct 27 '21 15:10 huyz

hi @huyz,

I am sorry that it is difficult for you to use py2puml. Is your git repository publicly available somewhere (in github or gitlab, for example), so that I can have a look?

It is not a good practice to have your python files directly at the root of your git project (see my previous answer and its link). As you can see in this https://github.com/huyz/flask-api repository that you forked, all the flask API code lies in the flask_api sub-directory. Because that is the content of this folder that get installed when you do pip install flask_api.

So if your project contains a single python file, git_project_folder/example_library.py for example, the PEP recommendation is to rename it into git_project_folder/example_library/__main__.py. Then you would be able to use py2puml like this:

cd git_project_folder
py2puml example_library example_library

And you would be able to run your script like this:

cd git_project_folder
python -m example_library
# example_library is a folder in this case, but the python interpreter will look for a __main__.py file to execute

# or
python example_library/__main__.py

lucsorel avatar Oct 27 '21 20:10 lucsorel

This is a work project. So I can't post it. (And I can't easily change the hierarchy, right now).

But how would you invoke py2puml for this https://github.com/huyz/py2puml-test

huyz avatar Oct 29 '21 15:10 huyz

hello @huyz

py2puml project project should work, but the library faces a module import error that I don't understand:

Traceback (most recent call last):
  File "/.../py2puml-test/.venv/bin/py2puml", line 8, in <module>
    sys.exit(run())
  File "/.../py2puml-test/.venv/lib/python3.8/site-packages/py2puml/cli.py", line 17, in run
    print(''.join(py2puml(args.path, args.module)))
  File "/.../py2puml-test/.venv/lib/python3.8/site-packages/py2puml/py2puml.py", line 17, in py2puml
    domain_item_module: ModuleType = import_module(name)
  File "/.../.pyenv/versions/3.8.6/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'project'

Is it the error you are facing?

Producing puml documentation for a root file (root.py) is not supported (it is not a recommended practice either)

lucsorel avatar Oct 31 '21 17:10 lucsorel

Is it the error you are facing?

Yes that's the error. This is why I'm confused

huyz avatar Oct 31 '21 17:10 huyz

Not working for me too. :|

basilmusa avatar Nov 24 '21 13:11 basilmusa

hello @basilmusa

I am sorry to read that the library does not work for you neither. Can you detail what your setup is (project structure, folders and files, the commands you tried), so that I can reproduce and investigate, if you please?

lucsorel avatar Nov 25 '21 08:11 lucsorel

I'm experiencing the same error as @huyz and @basilmusa when attempting to run py2puml project_folder project_folder on an Ubuntu VM. Not sure if this is related, but when I run py2puml directly on a python module it outputs an empty UML script:

@startuml
@enduml

Can py2puml be ran on any folder containing python scripts, or do these scripts need to be compiled into a package?

ColtAllen avatar Dec 06 '21 21:12 ColtAllen

@ColtAllen: some answers to your different questions:

  • py2puml is not actually made to be called on a module (a python script) directly. This is just historical: it was not my use-case. But I should change that during the end-of-year holidays :smiley:
  • I believe that py2puml can be run on any folder containing python scripts, as long as the folder path ("root_package/subpackage1") and the module chain ("root_package.subpackage1") passed as arguments are consistent. Typically, the py2uml command should be run in terminal positioned at the root of your git repo, at the level of the folder corresponding to the root package; which is the case of python projects following this structure: https://python-poetry.org/docs/basic-usage/#project-setup

But py2puml seems not as flexible as that for now. I will investigate that all along

lucsorel avatar Dec 17 '21 12:12 lucsorel

@lucsorel This issue crossed my mind again recently, and after looking through the Plant UML documentation, I think my problem is caused by the lack of class objects in the Python modules I'm using. Classes tend to be overkill for a lot of ML pipelines, but if PlantUML does not support the illustration of Python methods and the dependencies between them, I don't think this will be a viable documentation solution for any of my projects.

ColtAllen avatar Feb 12 '22 17:02 ColtAllen

hello @ColtAllen

Indeed, py2puml currently documents data structures (classes with static attributes or instance attributes defined in a constructor, dataclasses, namedtuple, enumerations). Someone proposed a pull request for documenting functions (#12, functions do not fit exactly as entities in the UML vision) but the author does not give signs of activity on it anymore :shrug:

lucsorel avatar Feb 13 '22 21:02 lucsorel

hi @Highlander1970 @huyz @basilmusa :slightly_smiling_face:

Please, forgive me for the long delay before solving this issue. It took me a while to understand how Python imports modules, specifically that Python uses the pathes listed in sys.path to look for the modules to inspect. The current working directory is added when using poetry whereas it is not when using native virtual environments.

:question: Would anyone of you be kind enough to review and approve #40 which fixes this issue, if you please? :pray:

The fix was short (see https://github.com/lucsorel/py2puml/pull/40/files#diff-7ff32e929e86cd812f60d9666a605c5b3d0a6cf13e938a4767ff538064e2b6c3R12) and a unit test checks that (https://github.com/lucsorel/py2puml/pull/40/files#diff-241c03bb18920b9ecd1bf42fd72007a92a4e08e44c95009d340ffb1fd0c3627dR31-R44).

As a maintainer, I appreciate to have the feedback of users (aside from adding issues :wink:). If you can't or don't have time, just let me know and I will validate the pull request myself.

You can test the fix on @huyz 's test project (https://github.com/huyz/py2puml-test):

git clone [email protected]:huyz/py2puml-test.git
cd py2puml-test
# assuming python3 below
python -m venv .venv
source .venv/bin/activate
pip install py2puml==0.7.1

py2puml project project
# -> this fails with "ModuleNotFoundError: No module named 'project'"

Then, modify py2puml-test/.venv/lib/python{your version}/site-packages/py2puml/cli.py as such:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from argparse import ArgumentParser

from pathlib import Path
from sys import path

from py2puml.py2puml import py2puml


def run():
    # adds the current working directory to the system path so that py2puml can import them
    current_working_directory = str(Path.cwd().resolve())
    if current_working_directory not in path:
        path.append(current_working_directory)

    argparser = ArgumentParser(description='Generate PlantUML class diagrams to document your Python application.')

    argparser.add_argument('-v', '--version', action='version', version='py2puml 0.7.1')
    argparser.add_argument('path', metavar='path', type=str, help='the filepath to the domain')
    argparser.add_argument('module', metavar='module', type=str, help='the module name of the domain', default=None)

    args = argparser.parse_args()
    print(''.join(py2puml(args.path, args.module)))

Then running py2puml project project should output the expected PlantUML diagram:

@startuml project
namespace project.__main__ {}
class project.__main__.App {
}
footer Generated by //py2puml//
@enduml

lucsorel avatar Mar 05 '23 01:03 lucsorel

@ColtAllen your participation on this issue was not really related to the pull request; but you are welcome for review or approval, if you like :pray: :slightly_smiling_face:

lucsorel avatar Mar 05 '23 01:03 lucsorel

I was able to get 0.7.2 to work on my simple example.

It's going to be a while until I can try it out on another full-blown project as I'm no longer working in Python at the moment.

Thanks for the fixes.

huyz avatar Mar 30 '23 17:03 huyz

Thank you @huyz for your feedback. I am glad that #40 fixed this issue :smiley:

lucsorel avatar Mar 31 '23 20:03 lucsorel