- Place a file named
.marker-filesomewhere in your file system. - From the directory containing the
.marker-file, or any (nested) subdirectory, you can now use useprojdirto find the path of the directory containing.marker-file:
import projdir
import whatever_package
base_dir = projdir.find(".marker-file") # returns a pathlib.Path object
indata_path = base_dir / "indata"
output_path = base_dir / "result.csv"
whatever_package.create_output_file(indata_path, output_path)- Let's say you are building a Python application (script, command-line tool, whatever) that relies on file system inputs or outputs.
- The expected file inputs or outputs do not have a fixed path compared to the Python script, and you don't want to hard-code an absolute path to the working directory.
- This is similar to Git's
.gitdirectory, which not only contains the repository database but also marks the root directory of the repository.
base_dir = projdir.find(".marker-file", dir_ok=False) # Match only files
base_dir = projdir.find(".marker-dir", file_ok=False) # Match only dirsSimple rule: projdir.find() always returns the containing directory. If you want the matching file or directory, this is easily done:
CONFIG_FILE_NAME = ".myappconfig"
base_dir = projdir.find(".myappconfig", dir_ok=False)
config_path = base_dir / CONFIG_FILE_NAMEprojdir.find(marker_relpath) always returns a directory base_dir such that base_dir / marker_relpath exists. This holds even if marker_relpath is a nested relative path.
# This will return the outer directory, the one that contains `subdirectory`
base_dir = projdir.find("subdirectory/with/marker-file")projdir.find()always searches from the current working directory.- If the marker cannot be found in the current working directory, the search continues step by step up the directory tree until the drive root, i.e. "/marker_relpath" on Unix or something like "C:\marker_relpath" on Windows.
- If the marker is not found, the custom
projdir.MarkerNotFoundexception is raised.MarkerNotFoundis a subclass ofFileNotFoundError. projdir.find()always returns an absolute path. Finding the result relative to the current working directory, without resolving symlinks, would be a little more complicated. I cannot see a use case for relative paths, but if you do, feel free to get in touch.