pythonpython-3.xpython-importpython-modulepython-packaging

How to import a module from a different folder?


I have a project which I want to structure like this:

myproject
├── api
│   ├── __init__.py
│   └── api.py
├── backend
│   ├── __init__.py
│   └── backend.py
├── models
│   ├── __init__.py
│   └── some_model.py
└── __init__.py

Now, I want to import the module some_model.py in both api.py and backend.py. How do I properly do this?

I tried:

from models import some_model

but that fails with ModuleNotFoundError: No module named 'models'.

I also tried:

from ..models import some_model

which gave me ValueError: attempted relative import beyond top-level package.

What am I doing wrong here? How can I import a file from a different directory, which is not a subdirectory?


Solution

  • Firstly, this import statement:

    from models import some_model
    

    should be namespaced:

    # in myproject/backend/backend.py or myproject/api/api.py
    from myproject.models import some_model
    

    Then you will need to get the directory which contains myproject, let's call this /path/to/parent, into the sys.path list. You can do this temporarily by setting an environment variable:

    export PYTHONPATH=/path/to/parent
    

    Or, preferably, you can do it by writing a pyproject.toml file and installing your package. Follow the PyPA packaging guide. After you have written your pyproject.toml file, from within the same directory, execute this to setup the correct entries in sys.path:

    pip install --editable .