Python - Get path of root project structure

I've got a python project with a configuration file in the project root. The configuration file needs to be accessed in a few different files throughout the project.

So it looks something like: <ROOT>/configuration.conf <ROOT>/A/a.py, <ROOT>/A/B/b.py (when b,a.py access the configuration file).

What's the best / easiest way to get the path to the project root and the configuration file without depending on which file inside the project I'm in? i.e without using ../../? It's okay to assume that we know the project root's name.


You can do this how Django does it: define a variable to the Project Root from a file that is in the top-level of the project. For example, if this is what your project structure looks like:

project/
    configuration.conf
    definitions.py
    main.py
    utils.py

In definitions.py you can define (this requires import os):

ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) # This is your Project Root

Thus, with the Project Root known, you can create a variable that points to the location of the configuration (this can be defined anywhere, but a logical place would be to put it in a location where constants are defined - e.g. definitions.py):

CONFIG_PATH = os.path.join(ROOT_DIR, 'configuration.conf')  # requires `import os`

Then, you can easily access the constant (in any of the other files) with the import statement (e.g. in utils.py): from definitions import CONFIG_PATH.


Other answers advice to use a file in the top-level of the project. This is not necessary if you use pathlib.Path and parent (Python 3.4 and up). Consider the following directory structure where all files except README.md and utils.py have been omitted.

project
│   README.md
|
└───src
│   │   utils.py
|   |   ...
|   ...

In utils.py we define the following function.

from pathlib import Path

def get_project_root() -> Path:
    return Path(__file__).parent.parent

In any module in the project we can now get the project root as follows.

from src.utils import get_project_root

root = get_project_root()

Benefits: Any module which calls get_project_root can be moved without changing program behavior. Only when the module utils.py is moved we have to update get_project_root and the imports (refactoring tools can be used to automate this).


All the previous solutions seem to be overly complicated for what I think you need, and often didn't work for me. The following one-line command does what you want:

import os
ROOT_DIR = os.path.abspath(os.curdir)