Making More to Relative Path to File to Work

alex_ber
alex_ber
Apr 11 · 3 min read

Without worrying about current working directory (Python).

What if you have some script or application that uses relative path and you want to invoke it from another directory. To get things more complicated. maybe your “external” code also use relative path, but relative to another directory. Here, I will describe the recipe how you can make all of these to work.

Suppose, that you wrote some script or application that is packaged and installed as YourApp (that is, it is installed into site-packages or venv). Something like this:

Code of app.py:

Note: Here I’m using init_app_conf module. You can read about it here.

Typically, at the end of the script/application’s main() function there are following lines:

They are designed to forward the call to the main()function when the file is called as script, typically from the the directory where app.py is laid down (cd YourApp) something like this is called: python app.py.

Now, what if you want to call app.py (or it’s main() function) from another directory?

If you have code such as in line 17, it will just fail. The essential problem their that my code use relative path, so it assumes that my working directory is the same as app.py file.

An alternative approach may be to supply some runner.py file, something like this:

Note, that this file also don’t have:

at the end.

It basically, calls app.py main() function decorated by FixRelCwd context-manager. I will get back to FixRelCwd below.

Now, in some unrelated directory, you should have something like this:

This is “real” main method. If you want to put some extra code before or after the app.py main() function. You can put it in lines 15 and 17.

Here you can read my story that describes my way to configure logging.

Here you can read about fixabscwd() function in mains module or Making relative path to file to work.

To put simple, besides lines 2 and 16 this is typical main() function. I want among many other thing to call app.py script/application that is installed in YourApp package. To make in concrete, the following code was executed:

So, because we installed YourApp package we can import (the wrapper of, why it is important that it is wrapper will be clear below) main() function at line 2 and make regular call to it whenever it is appropriate (we can add some code before and/or after it, if we will).

Let’s quickly some-app, what we have. We have YourApp script application. It is installed into site-packages or venv. It has app.py file with main() function that does some computation. We have some “wrapper” runner.py with main() function decorated by FixRelCwd context-manager. And we have some “real” file with “real” main() function as above.

So, the real power is in FixRelCwd.

How FixRelCwd works?

FixRelCwd is context-manager. It takes relPackage and, optionally, logger.
It temporary changes current working directory to the one where relPackage is installed. If logger is not specified, than some default one will be used.

If this function is called in REPL or IPython notebook it does nothing.

This function wasn’t tested from frozen python script (frozen using py2exe), but it should work (by doing nothing).

Basically, first it stores os.chdir for the later use, than it looks for __file__ attribute in the relPackage module, takes directory from there and set cwd to it (by calling toos.chdir).

On the exit, it restores os.chdir, so your “external” code can operate as usual.

The source code you can found here. It is available as part of my AlexBerUtils s project.

You can install AlexBerUtils from PyPi:

python3 -m pip install -U alex-ber-utils

See here for more details explanation on how to install.

Geek Culture

Proud to geek out.

Sign up for Geek Culture Hits

By Geek Culture

Subscribe to receive top 10 most read stories of Geek Culture — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store