rootutils
rootutils (formerly pyrootutils) is a Python library designed for simple and robust project root setup. It helps locate the project root directory using an indicator file and can optionally add it to `sys.path` for simplified imports. The library is currently at version 1.0.7 and maintains a moderately active release cadence, typically releasing minor updates or bug fixes every few months.
Warnings
- breaking The library was officially renamed from `pyrootutils` to `rootutils` starting from version 1.0.5. This affects both the PyPI package name and all import statements.
- gotcha `rootutils.find_root()` only returns the path to the project root and does NOT modify `sys.path` by default.
- gotcha The library relies on an `indicator_file` (e.g., `.project-root`) to identify the project root. If this file is missing or `project_dir` is incorrectly specified, functions like `find_root` or `autosetup` will fail to locate the root.
Install
-
pip install rootutils -
pip install pyrootutils # For versions < 1.0.5
Imports
- find_root
from rootutils import find_root
- setup_root
from rootutils import setup_root
- autosetup
from rootutils import autosetup
Quickstart
import rootutils
import os
import sys
# Simulate a project root by creating an indicator file in the current directory.
# In a real project, you would call this from a subdirectory.
indicator_file = ".project-root"
with open(indicator_file, "w") as f:
f.write("")
try:
# Find the project root (current directory in this simulation)
# and add it to sys.path for simplified imports.
root_dir = rootutils.autosetup(
indicator_file=indicator_file, # The file to look for
project_dir=os.getcwd(), # Start search from current directory
add_to_pythonpath=True # Explicitly ensure it's added
)
print(f"Project root found: {root_dir}")
print(f"Does sys.path contain project root? {str(root_dir) in sys.path}")
# Example: In a real project, if you have a 'config' directory at the root,
# you could now do: 'from config import settings'
# without complex relative imports.
finally:
# Clean up the simulated indicator file
if os.path.exists(indicator_file):
os.remove(indicator_file)