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'
Related
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
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?
I am looking to parse an excel data file and would like to make it so that my program automatically fills out the file path based on the file location of the current python file I am using.
For example, in the code
categorization_file = r'C:\Users\Name\Desktop\ExcelFile.xlsx'
inputVariables = categorization_file.parse(sheet_name='Control')
I would like the "r'C:\Users\Name\Desktop\" part to be automatically generated if possible. This path will be common with the file I am running my program from.
Thanks
import os
# to get the location of the current python file
basedir = os.path.dirname(os.path.abspath(__file__))
# to join it with the filename
categorization_file = os.path.join(basedir,'ExcelFile.xlsx')
The os module is what you're looking for.
import os
os.getcwd()
Use os.path.dirname like this:
import os
base_dir = os.path.dirname('C:\Users\Name\Desktop\ExcelFile.xlsx')
or even better:
import os
filepath = 'C:\Users\Name\Desktop\ExcelFile.xlsx'
base_dir = os.path.dirname(filepath)
In both cases, base_dir will now evaluate to 'C:\Users\Name\Desktop\'
Hope this helps!
This will give you the full path where the script is
import os
path = os.path.dirname(os.path.realpath(__file__))
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()
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.