If the question is not clear, Let me give an example. Suppose this is my project structure:
app.py dir1 ... Workflow.py ... config.yml
In app.py
I import Workflow
. Workflow.py
reads from config.yml
. If I want to run workflow.py
individually I can simply give the file path as config.yml
because it is in the same folder. However, when I import Workflow
in app.py
and run it, the path can not be resolved. If I change the path in workflow.py
as dir1/config.yml
, app.py
runs successfully but now workflow.py
does not run.
I want to be able to run both the file individually. How do I resolve this path issue?
Thank you very much in advance
Advertisement
Answer
Here is how you directory structure looks like:
rootdir ├───app.py └───dir1 ├───workflow.py └───config.yml
For example, workflow.py
looks like this:
def run(): with open('config.yml') as c: print(c.read()) if __name__ == '__main__': run()
Running python app.py
from rootdir, will produce an error due to the fact that config.yml
is a relative path and it is relative to your current working directory which is rootdir
and rootdir/config.yml
does not exist.
Running python workflow.py
from dir1 would succeed, because the relative path would point to an existing file in this case.
Simple Solution
You could make the path different depending on how the script was called using the __name__
variable:
CONFDIR = 'dir1' def run(): with open(f'{CONFDIR}/config.yml') as c: print(c.read()) if __name__ == '__main__': CONFDIR = '.' run()
This way, the if block will get executed only if the script is run directly (python workflow.py
) and the import from app.py will work correctly.
On the other hand, if you wanted to run python dir1/workflow.py
from rootdir
, it would fail, because the relative path to config is wrong again.
Better Solution
You could create an environment variable and store the path to the file there. workflow.py
would look like this:
import os def run(): with open(os.environ.get("CONFIG_PATH", "./config.yml")) as c: print(c.read()) if __name__ == '__main__': run()
Run app.py
like this:
CONFIG_PATH="dir1/config.yml" python ./app.py
Run workflow.py
like this:
CONFIG_PATH="./config.yml" python ./workflow.py
or like this if CONFIG_PATH
is not set:
python ./workflow.py
This way the path to the configuration file is also configurable and you don’t need to hardcode it. It also provides a default value of ./config.yml
if CONFIG_PATH
is not set.