Search code examples
pythonioworking-directory

how to get the path to file with python when working directory is different


Consider the following Python file structure

Root  
  |---- SubFolder  
  |        |---- generator.py    
  |        |---- config.json        
  |  
  |---- main.py  

main.py:

import os 

def main():
    from SubFolder.generator import start

    start(__file__)
    
if __name__ == '__main__':
   
    main()

generator.py

import os 
def start(caller: str):

    file_path_s = "./config.json"
    file_path_l = "./SubFolder/config.json"

    exist_s = os.path.exists(file_path_s)
    exist_l = os.path.exists(file_path_l)

    print(f"Caller: {caller}")
    print(f"cwd:{os.getcwd()}")

    print(f"exist {file_path_s}: {exist_s}")
    print(f"exist {file_path_l}: {exist_l}")

if __name__ == '__main__':
    
    start(__file__)

The probplem:

  1. generator.start() can be called from main.py as well as from generator.py itself (executed as main)

  2. accordigly the working directory is different

  3. when start() wants to read the json, the path to to the json is different each case.

    when called from main it should use ./SubFolder/config.json
    when called from generator it should use ./config.json

Is there a way to figure out the path to use without the start() will do something like the following:

def _get_config_path():
    work_dir = os.getcwd()
    sub_folder = "SubFolder"

    index = work_dir.rfind(sub_folder)
    expected = len(work_dir) - len(sub_folder)  
    
    if  index == expected:
        return   "./config.json"
    else:
        return   "./SubFolder/config.json"

how this can be achived?


Solution

  • In generator.py just use a relative path to your config

    from pathlib import Path
    def start(caller: str):
        config_path = Path(__file__).parent / "config.json"
        if config_path.exists():
            print(f"config exists:  caller {caller} does not matter")
        
    if __name__ == '__main__':    
        start(__file__)
    

    Then it doesn't matter who calls it.