Python relative path to a specific file - python

I have a folder structure like:
Project/Main.py Project/Module/Data.py
Project/Config/config.ini
Edits: Main.py uses Data.py. Only in Data.py I use config.ini. The application is run from Main.py but also from Data.py. The problem is that every time I run it from this separate scripts(one time the path is Config/config.ini, other time is ../Config/config.ini), I need to change this relative path, from Main.py is a path, from Data.py is another path.
How can I achieve to run from Main.py and Data.py and use the same piece of code to identify the config.ini?
Thanks

Put in your Main.py:
import os.path
BASE_DIR = os.path.dirname(__file__)
CONFIG_DIR = os.path.join(BASE_DIR, 'Config', 'config.ini')
And in your Data.py
import os.path
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
CONFIG_DIR = os.path.join(BASE_DIR, 'Config', 'config.ini')
Now you have CONFIG_DIR defined in both scripts, pointing to your config.

Related

python not able to find the certificate file path

My program structure is of the form:
-worker
-worker
--lib
----file.py
----cert.pem
-app.py
Inside file.py I have following code:
import os
BASE_DIR = os.path.dirname(__file__)
filepath = os.path.join(BASE_DIR, 'cert.pem')
When I run the service which is through app.py, it fails at file.py line L2 stating:
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: /usr/local/lib/python3.7/dist-packages/worker/lib/../lib/cert.pem
Could someone have any idea why python is taking "lib" directory twice and putting ".." in between?
pathlib is usually best to handle paths.
import pathlib
BASE_DIR = pathlib.Path(__file__).parent.absolute()
filepath = BASE_DIR / "cert.pem"
print(filepath)
# >>> /Users/felipe/Desktop/example_project/cert.pem
Note the example.py (above) is also inside example_project folder.
AS posted by #Selcuk: This worked for me.:
BASE_DIR = os.path.realpath(os.path.dirname(__file__)) – Selcuk

Python access to project root directory

Below folder structure of my application:
rootfolder
/subfolder1/
/subfolder2
/subfolder3/test.py
my code inside of the subfolder3. But I want to write output of the code to subfolder1.
script_dir = os.path.dirname(__file__)
full_path = os.path.join(script_dir,'/subfolder1/')
I would like to know how can I do this wihout importing full path to directory.
It sounds like you want something along the lines of
project_root = os.path.dirname(os.path.dirname(__file__))
output_path = os.path.join(project_root, 'subfolder1')
The project_root is set to the folder above your script's parent folder, which matches your description. The output folder then goes to subfolder1 under that.
I would also rephrase my import as
from os.path import dirname, join
That shortens your code to
project_root = dirname(dirname(__file__))
output_path = join(project_root, 'subfolder1')
I find this version to be easier to read.
The best way to get this done is to turn your project into a module. Python uses an __init__.py file to recognize this setup. So we can simply create an empty __init__.py file at the root directory. The structure would look like:
rootfolder
/subfolder1/
/subfolder2
/subfolder3/test.py
__init__.py
Once that is done, you can reference any subfolders like the following:
subfolder1/output.txt
Therefore, your script would look something like this:
f = open("subfolder1/output.txt", "w+")
f.write("works!")
f.close()

Create a utility function that retrieves the user-executed script's dir

There are multiple threads about getting the current Python's script directory, for example:
import os
dir = os.path.dirname(os.path.abspath(__file__))
The question is, what should I do if I want to add this function into some utility file, while I want the returned value to be the directory of the calling file, in this case, the file executed by the user?
What would happen here?
// utils.py
def get_script_dir():
import os
return os.path.dirname(os.path.abspath(__file__))
// main_app.py
from utils import get_script_dir
print(get_script_dir())
// user's shell
python c:\path\to\somewhere\main_app.py
Will it print the directory of main_app.py or the directory of utils.py? What is an elegant solution for placing the function in the utils file while getting the directory of the file that was actually executed by the user?
Please try following and let me know whether it's exactly what you want:
# utils.py
def get_script_dir():
import sys
import os
return os.path.dirname(sys.modules['__main__'].__file__)
# main_app.py
from utils import get_script_dir
print(get_script_dir())
Supposing that your project directory tree is like the following:
Python/
main.py
modules/
utils.py
__init__.py
Being Python/modules/utils.py:
import os
get_script_dir = lambda file: os.path.dirname(os.path.abspath(file))
and Python/main.py:
from modules import utils
import os
script_dir = utils.get_script_dir(__file__)
print("[i] Currently executing file {} located at {}".format(os.path.basename(__file__), script_dir))
Executing Python/main.py is going to output something like:
[i] Currently executing file main.py located at C:\Users\BlackVirusScript\Desktop\Python

Referencing relative directories outside of project

In one of my apps, I want to load some data from another directory on my machine. My Django project is located at C:/Projects/MyProject, my app is located at C:/Projects/MyProject/myapp, and my data directory is located at C:/Data/MyAppData. For various reasons, I do not want to store this data directly in the app's static directory. How can I do this?
Here is what I have tried. In C:/Projects/MyProject/settings.py, I have the following:
import os
DATA_ROOT = `C:/Data`
DATA_DIR = os.path.join(DATA_ROOT, 'MyAppData')
But how do I now reference DATA_DIR in my views file?
Also, suppose that I want to keep everything relative, and avoid hard-coding C:/Data. Is this possible? Something like the following:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATA_ROOT = BASE_DIR + '../../../Data'
DATA_DIR = os.path.join(DATA_ROOT, 'MyAppData')
BASE_DIR + '../../../Data' does not contains appropriate separate in between. Use os.path.join there, too.
BTW, os.path.join accepts multiple arguments. So you can write as follow:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATA_ROOT = os.path.join(BASE_DIR, '../../../Data', 'MyAppData')
# To get absolute path
DATA_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../../../Data', 'MyAppData'))
To access the DATA_ROOT in views, import settings in the view:
from django.conf import settings
# Do something with `settings.DATA_ROOT`
UPDATE
If you use Python 3.4+, you can use pathlib:
DATA_ROOT = pathlib.Path(__file__).resolve().parents[3] / 'Data' / 'MyAppData'

Get parent directory of a specific file

There is a file a.py.
The location is /home/user/projects/project1/xxx/a.py.
If I call os.getcwd(), it gives me /home/user/projects/project1/xxx/. But I want to reach /home/user/projects/project1. How can i do this in Python?
Edit : I think i must be more clear. i want this for my Django project.
i use these codes in my settings.py:
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
then i use fallowing code to specify where my static file folder is. :
os.path.join(PROJECT_PATH,'statics'),
my settings.py file is under: /home/user/projects/project1/xxx/settings.py
my static file folder is under same dir as settings.py.
now i want to move this folder to /home/user/projects/project1
what should i do with code that in settings.py
thank you
from os.path import dirname
print(dirname(dirname(__file__)))
Each time you call dirname it gives you parent directory. Call as many times as necessary.
Alternatively you can do following:
normpath(join(path1, '..', '..'))
>>> import os
>>> os.getcwd()
'/tmp/test'
>>> os.chdir('..')
>>> os.getcwd()
'/tmp'
>>>
The dot dot (..) represents the parent directory. Because relative path names specify a path starting in the current directory.
See the documentation of os.chdir.

Categories

Resources