Python 3 modules: user configurable relative directories? - python

So I have a convention (perhaps it is a bad one) that I structure my python packages somewhat like this:
<py-pkg>
__init__.py
settings.py
subpkg/
__init__.py
module.py
...
where in settings.py
'''-----------------------------------------------------------------------------
DIRECTORIES AND FILES
-----------------------------------------------------------------------------'''
MODULE_DIR = os.path.dirname(os.path.realpath(__file__))
PROJECT_DIR = os.path.join(MODULE_DIR, '..')
DATA_DIR = os.path.join(PROJECT_DIR, 'data')
SOURCE_DIR = os.path.join(DATA_DIR, 'source')
DERIVED_DIR = os.path.join(DATA_DIR, 'derived')
# other relevant relative paths to default files / paths
While this works often quite well for me, it may be the case where say the user wants to update DATA_DIR and all dependent paths.
How could I make that configurable?

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()

Python relative path to a specific file

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.

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