Search code examples
pythonpython-importimporterrorproject-structure

Absolute/relative import in Python: ModuleNotFoundError and more


This is my project structure:

- config
- data
- src
    - resources 
    - db
- test

N.B.: I am using Python 3.9 and every folder that contains a .py file also has a __init__.py file

All the scripts I want to run are located in the /src folder and they used code from other scripts placed in the /src/resources folder (which is basically acting like a library). Some of these scripts also read YAML files from the /config folder

Here is the problem, I cannot find a way to properly run these scripts from the command line, I am always getting errors like:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/runpy.py", line 185, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/local/lib/python3.8/runpy.py", line 111, in _get_module_details
    __import__(pkg_name)
  File "/home/pi/crypto/src/ethMessage.py", line 4, in <module>
    import update_db
  File "/home/pi/crypto/src/update_db.py", line 1, in <module>
    from db.mysql_main import insertValueAndFee
  File "/home/pi/crypto/src/db/mysql_main.py", line 6, in <module>
    from src.resources.parser import read_yaml
ModuleNotFoundError: No module named 'src'

I tried both with relative and absolute import, right now absolute import is what I am using (e.g. from src.resources.parser import read_yaml)

Which is the proper way to run scripts from the command line?

EDIT:

As you suggested, I added

sys.path.append( os.path.abspath(os.path.dirname(__file__)+'/..') )

to all the main scripts, and I am still getting a similar error:

Traceback (most recent call last):
  File "src/ethMessage.py", line 6, in <module>
    import update_db
  File "/home/pi/crypto/src/update_db.py", line 1, in <module>
    from db.mysql_main import insertValueAndFee
  File "/home/pi/crypto/src/db/mysql_main.py", line 6, in <module>
    from src.resources.parser import read_yaml
ModuleNotFoundError: No module named 'src'

To clarify, I am running my script from the global folder, which in my case is named "crypto". I am also open to change the project structure with one that doesn't create problems.


Solution

  • If someone is still looking for a solution, I highly recommend not to bother with Python's imports: they are probably the worst part of the whole language.

    Instead, if you want to use some files as a library, you should use setuptools to create a package from those files.

    Then, you can install it locally or publish it on PyPi.

    This way, you can import your library in a script just like another third-party module, (e.g. requests, selenium, ...), and things will work, instead of giving you a headache because a file is in a directory instead of another.