django [Errno 2] No such file or directory: - python

I've built a script to read an excel file and save the contents into my database. (Note: the file and the script are in different directories). However, when I try to execute the script from my views.py as a simple import, django throws an error that it cannot find the file or directory:
[Errno 2] No such file or directory: '\\media\\documents\\GDRAT.xls\\'
My actual code in the script looks like this:
source_wb = xlrd.open_workbook('media/documents/GDRAT.xls')
Where my script is in the parent directory. Executing the script from the command line works just fine, so I'm struggling with why django is reading it differently.
My views.py function looks like this (Note: I go back to the parent directory to find the script - which seems to work fine, just can't find the excel file I need to read in):
def UpdateGDRAT(request):
os.chdir('..')
import GDRAT
return render_to_response('success.html')
Any guidance is greatly appreciated!

This works for me
os.path.join(os.path.dirname(os.path.dirname(__file__)),'media/documents/GDRAT.xls')

settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
from django.conf import settings
import os
base_dir =settings.MEDIA_ROOT
my_file = os.path.join(base_dir, str(GDRAT.xls))

when you run a script from the terminal, you have a current working directory from which any relative path starts, when calling the same script from another code your working directory could be different.
If you know the position of the file relative to the script, I suggest you to use an absolute path constructed dynamically like this:
import os
GDRAT_abs_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'media/documents/GDRAT.xls')
__file__ gives you the path of the current file that is the script (assuming this line is placed in the script);
for dirname see http://docs.python.org/2/library/os.path.html#os.path.dirname
for realpath see http://docs.python.org/2/library/os.path.html#os.path.realpath

Related

How to load a file by relative path in python?

My directory structure like below:
./outputsetting.json
./myapp/app.py
I load outputsetting.json file in app.py like below:
with open("..\outputpath.json","r") as f:
j=json.load(f)
And run in myapp directory it's ok:
python app.py
But if I run app.py in the parent directory:
python .\myapp\app.py
It raise error
FileNotFoundError: [Errno 2] No such file or directory: '..\\outputpath.json'
How can I load file from disk by the relative directory to the app.py? So I can run it from any place and needn't modify code every time.
Thanks!
When you start the script from the parent directory, the working directory for the script changes. If you want to access a file that has a specific location relative to the script itself, you can do this:
from pathlib import Path
location = Path(__file__).parent
with open(location / "../outputsetting.json","r") as f:
j=json.load(f)
Path(__file__) gets the location of the script it is executed in. The .parent thus gives you the folder the script is in, still as a Path object. And you can then navigate to the parent directory from that with location / "../etc"
Or of course in one go:
with open(Path(__file__).parent / "../outputsetting.json","r") as f:
j=json.load(f)
(Note: your code says outputpath.json, but I assume that's the same outputsetting.json)
Another solution would be to just change the working directory to be the folder the script is in - but that of course only works if all your scripts and modules are OK with that change:
from pathlib import Path
from os import chdir
chdir(Path(__file__).parent)
with open("../outputsetting.json","r") as f:
j=json.load(f)
I'd prefer constructing the absolute path as in the previous example though.

Python module that imports from subdirectory can't find images located in there

I have project that I decided to divide into subfolders. My main module main.py imports other module mod1.py from a subfolder. The imported module mod1.py uses images that are located in another subfolder and refers to them relatively. I can't use absolute path from the drive, but I know the relative path from the beginning of the project structure.
The situation is illustrated below somehow
project
├── main.py
└───subfolder
├───mod1.py
└───pictures
└───pic1.png
So there's a line in mod1.py:
image = Image.open("./pictures/pic1.png")
and when I import mod1.py in main.py and run the program I get an error:
FileNotFoundError: [Errno 2] No such file or directory: './pictures/pic1.png'
How to access those pictures when I run main.py and import a module that relatively refers to them?
I have __init__.py file in the subfolder and all the imports are working.
try this
try:
image = Image.open("pictures/pic1.png")
except FileNotFoundError:
image = Image.open("subfolder/pictures/pic1.png")
so python will try the first path, if it fails, it will try the second, which looks for the main.py file
While Jorge's answer may work in some cases I suggest understanding why yours does not work and look how other people have solved this problem. Lets take a very simple example.
project
dir1
test.py
dir2
test2.py
Lets assume the full path to my project directory is located at /Users/sstacha/tmp/test_python/ and my 2 test files contain the following
test.py
import os
from pathlib import Path
from dir2.test2 import function2
def function1():
path = os.getcwd()
print(f"function1.os.cwd(): {path}")
DIR = Path(__file__).resolve()
print(f"function1.pathlib_path: {DIR}")
function1()
function2()
test2.py
import os
from pathlib import Path
def function2():
path = os.getcwd()
print(f"function2.os.cwd(): {path}")
DIR = Path(__file__).resolve()
print(f"function2.pathlib_path: {DIR}")
if i execute python dir1/test.py from the project directory I get the following output:
$ python dir1/test.py
function1.os.cwd(): /Users/sstacha/tmp/test_python
function1.pathlib_path: /Users/sstacha/tmp/test_python/dir1/test.py
function2.os.cwd(): /Users/sstacha/tmp/test_python
function2.pathlib_path: /Users/sstacha/tmp/test_python/dir1/dir2/test2.py
if I instead cd to dir1 and execute python test.py I get this output:
$ python test.py
function1.os.cwd(): /Users/sstacha/tmp/test_python/dir1
function1.pathlib_path: /Users/sstacha/tmp/test_python/dir1/test.py
function2.os.cwd(): /Users/sstacha/tmp/test_python/dir1
function2.pathlib_path: /Users/sstacha/tmp/test_python/dir1/dir2/test2.py
So your actual problem is that os.cwd() will always be set to whatever directory the os was set to when the python command was run. I also included a line from how the Django settings file handles this issue for python >= 3.4. As you can see, this approach will be relative to whatever file your function is defined in which should be a better / more portable solution regardless of what directory the python executable is called from.
Hopefully that helps you understand your issue better and a possible solution that might work for you.
I realized I never really fully answered the question here would be an example:
DIR = Path(__file__).resolve().parent
image = Image.open(DIR+"/pictures/pic1.png")
By the way if you are using a version earlier than 3.4 this is how the Django settings file approached it:
DIR = os.path.dirname(os.path.abspath(__file__))
image = Image.open(DIR+"/pictures/pic1.png")

python: Unable to open json file from another directory?

My tests are at:
src/com/xyz/tests/api_test/<Test File>
My test file calls my libraries at:
src/com/xyz/libs/api_libs/<Library File>
My library file has to open a JSON file at:
src/com/xyz/libs/api_libs/configs/<Config File>
In my library file, since its at the same parent directory as the JSON configs, I have used the following code to open the JSON.
with open('configs/sample_wlan_json'):
<Do Some action>
I tried various paths like:
.../libs/api_libs/configs/<ConfigFileName>
src/com/mist/libs/api_libs/configs/<ConfigFileName>.json
The whole path from /Users/...... but nothing seems to work.
A relative path is relative to the current working directory. Current working directory depends on how an application is started, and not where it is.
So, if you want to have a path relative to your source code, you should not rely on the current working directory, but construct the absolute path instead.
You can construct a path which is relative to your source code by using the __file__ variable, which is the path to the current py file.
Something like this should work:
configs_dir = os.path.join(__file__, '..', 'configs')
with open(os.path.join(configs_dir, 'sample_wlan.json'), 'rt') as f:
...

FileNotFoundError: [Errno 2] when using sphinx and autodoc

I am trying to use sphinx to run an autodoc. My project structure like this:
Where the python files are reading from input/input.xlsx.
My conf.py looks like:
import os
import sys
sys.path.insert(0, os.path.abspath('../../'))
extensions = ['sphinx.ext.autodoc']
I run the ./docs/sphinx-apidoc -o ./source ../ where it creates a:
module.rst
and:
My_Project.rst
inside the ./docs/source.
My issue is that when I build the make html, it gives me errors like:
FileNotFoundError: [Errno 2] No such file or directory: './input'
However, as I have set in conf.py, it should logically go two levels high and one level down to /input folder.
../../input
Appreciate any ideas.
Finally I figured out something that worked for me. Beforehand, I need to clarify something: in one of python files located in ../../ from my source directory, the code is reading an excel file from this path ./input/input.xlsx. I figured out that defining a hard coded path is the source of this issue. So I fixed it with following code:
directory_path = os.path.dirname(os.path.abspath(__file__))
new_path = os.path.join(directory_path, "input.xlsx")

Script writes file in wrong directory

I just experienced a weird behaviour in Python.
I created a copy of a script.py file in a sub-folder within the folder that contains the initial script.
The script at the end exports some data into a .txt file by using:
with open('clayList.2203.txt', 'w',encoding='utf-8') as f:
for item in claysUniqueList:
f.write("%s\n" % item)
The problem is that Python writes the new file on the parent directory instead of the current one.
I checked the path with:
print(sys.path[0])
and it prints the current path correctly.
By default, relative paths are relative to the working directory, that is the directory from which is run the command that run the script.
If you want the path to be relative from the script directory, you will have to explicitly code this behaviour:
import os
filepath = os.path.join(os.path.dirname(__file__), 'clayList.2203.txt')
with open(filepath, 'w',encoding='utf-8') as f:
# ...
When you run code in Visual Studio, there are debugging options.
One of these it the directory to run from, called "Working directory".
(Right click your project and go to settings).
To run from the sub-directory you need to change this.
If you want to start in a sub directory, type that in instead, in the "working directory" shown here:
path for creating the file should be relative to the directory of execution
e.g. your pwd is parent and your script is in parent/child1/child2/script.py then path of the file to be created should be ./child1/child2/clayList.2203.txt

Categories