How to open file in django - python

I'm trying to open a file that is in the same directory as the app from views.
-app
--views.py
--about.txt
--...
My code to open the file is..
def home(request):
with open('about.txt','r') as f:
about = f
about = about.split('\n')
about = '<br/>'.join(about)
return render(request, 'app/home.html', {'about':about})
But I keep getting an error of `
FileNotFoundError at /
[Errno 2] No such file or directory: 'about.txt'
After thinking about this, I thought of putting it in a static dir but it would still give the same error.
I am still quite a beginner at django.
Django 2.2.3
Python 3.7.3
Edit:
I don't know if this is the reason... but when pressing enter for new line, it makes it on a new indentation.

TL;DR
You have to prepend your path with something like app to create app/about.txt. I have insufficient information to tell you exactly what, but here is how to find out:
When you run your app, the working directory is probably not in app. You can figure out what path it is running in by using os.getcwd(). For example:
import os
# ...
def home(request):
print(os.getcwd())
with open('about.txt','r') as f:
about = f
about = about.split('\n')
about = '<br/>'.join(about)
return render(request, 'app/home.html', {'about':about})
As #KlausD. mentioned, your path is relative. Whenever code is being run, it is run in a "working directory". For example, if I ran python views.py in the app directory, the current working directory (cwd for short) would be app. Then, when a relative path is given, like about.txt (which really means ./about.txt, where . represents the cwd), it looks in the cwd for about.txt.

Related

Can't find the file from views.py

I am stuck with a really weird problem.
I have a file called: "test.txt".
It is in the same directory with views.py. But I can't read it... FileNotFoundError.
But if I create read_file.py in the same directory with views.py and test.txt, it works absolutely fine.
What is wrong with views? Is this some sort of restriction by Django?
This code works on read_file, doesn't work on views.py:
fkey = open("test.txt", "rb")
key = fkey.read()
I think the problem may be relative vs absolute file handling. Using the following Python snippet, you can work out where the interpreter's current working directory is:
import os
print(os.getcwd())
You should notice it's not in the same directory as the views.py, as views.py is likely being invoked/called from another module. You may choose to change all your open calls to include the whole path to these files, or use an implementation like this:
import os
# This function can be used as a replacement for `open`
# which will allow you to access files from the file.
def open_relative(path, flag="r"):
# This builds the relative path by joining the current directory
# plus the current filename being executed.
relative_path = os.path.join(os.path.dirname(__file__), path)
return open(relative_path, flag) # return file handler
Then, this should work:
fkey = open_relative("test.txt", "rb")
key = fkey.read()
Hope this helps!

How to load resources file without giving entire path in Python

I want to read the properties file in Python without giving the entire path. Because if my code is deployed somewhere else then my package would fail if I pass the hardcore value. So below is my code to read the properties file by giving the entire path:
import configparser
config = configparser.RawConfigParser()
config.read('C:\\Users\\s\\IdeaProjects\\PysparkETL\\src\\main\\resources\\configs.properties')
dbname = config['DB']['dbname']
username=config['DB']['user']
password=config['DB']['password']
table=config['DB']['tablename']
driver=config['DB']['driver']
print(dbname)
and below is my configs.properties file:
[DB]
dbname=ourdb
user=root
password=root
tablename=loadtable
driver=com.mysql.cj.jdbc.Driver
I tried different ways like ConfigParser instead of RawConfigParser but didn't work. Is there any way to load files from the classpath?
Also, I tried different ways from this link but it didn't help. All I need is a path to pass it to config.read method but it should not be hardcoded as I did it in the code.
Below is my project structure:
Also, as suggested I tried below code and passed the URL to the config.read method but it's not working.
props = os.path.join(
os.path.dirname("resources"), # folder where the python file is
'src/main/resources/configs.properties'
)
config.read(props)
I get below error:
raise KeyError(key)
KeyError: 'DB'
if the file will always be in the same place relative to your python file, you can do the following:
props = os.path.join(
os.path.dirname(__name__), # folder where the python file is
'relative/path/to/configs.properties'
)

Using DJANGO_SETTINGS_MODULE in a script in subfolder

In order to populate the database of my Django application, I created a small script that reads a CSV (a list of filenames) and creates objects accordingly:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
import django
django.setup()
import csv
import sys
from myapp.models import Campaign, Annotation
campaign_name = "a_great_name"
path_to_csv = "filenames.csv"
with open(path_to_csv) as f:
reader = csv.reader(f)
filenames = [i[0] for i in reader]
new_campaign = Campaign.objects.create(name=campaign_name)
for i in filenames:
new_annotation = Annotation(
campaign=new_campaign,
asset_loc = i)
new_annotation.save()
I saved this script at the root of my project: myrepo/populator.py
and it worked fine.
… until I decided to move it into a subfolder of my project (it’s a bit like an admin tool that should rarely be used): myrepo/useful_tools/import_filenames/populator.py
Now, when I try to run it, I get this error: ModuleNotFoundError: No module named 'myproject'
Sorry for the rookie question, but I’m having a hard time understanding why this happens exactly and as a consequence, how to fix it. Can anybody help me?
Yes, the problem arose when you changed the script location because then the root directory was not in the sys.path list anymore. You just need to append the root directory to the aforementioned list in order to be able to load the settings.py file of your project.
If you have the script now in myrepo/useful_tools/import_filenames/populator.py, then you will need to go back three folders down in your folders tree to be back in your root directory. For this purpose, we can do a couple of tricks using the os module.
import os
import sys
sys.path.append(os.path.abspath(os.path.join(__file__, *[os.pardir] * 3)))
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django
django.setup()
print('loaded!')
# ... all your script's logic

Code that only execute once, Python Startup folder

Hey and thanks for all of your answers. I try to write a piece of python code that only executes once, (first time the program is installed) and copies the program into the windows startup folders.
(C:\Users\ USER \AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup)
That's the code i wrote for this. (Please don't judge me. I know it's
very shitty code. But I'm very new to coding. (this is the second
little program i try to write)
import os
import shutil
#get username
user = str(os.getlogin())
user.strip()
file_in = ('C:/Users/')
file_in_2 = ('/Desktop/Py Sandbox/test/program.py')
file_in_com = (file_in + user + file_in_2)
folder_seg_1 = ('C:/Users/')
folder_seg_2 = ('/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup')
#create FolderPath
folder_com = (folder_seg_1 + user + folder_seg_2)
shutil.copy2(file_in_com, folder_com)
Because i got an error, that there is no such internal, external,
command, program or batch file named Installer. I tried to generate a batch file with
nothing in it that executes when the installation process is finished.(But the error is still there.)
save_path = 'C:/Windows/assembly/temp'
name_of_file = str("Installer")
completeName = os.path.join(save_path, name_of_file+".bat")
file1 = open(completeName, "w")
file1.close()
The main idea behind this that there is my main Program, you execute
it it runs the code above and copies itself to the startup folder.
Then the code the whole installer file gets deleted form my main
program.
import Installer
#run Installer File
os.system('Installer')
os.remove('Installer.py')
But maybe there's someone out there who knows the answer to this problem.
And as I said earlier, thanks for all of your answers <3.
BTW I'm currently using Python 3.5.
Okay guys now I finally managed to solve this problem. It's actually not that hard but you need to think from another perspective.
This is now the code i came up with.
import os
import sys
import shutil
# get system boot drive
boot_drive = (os.getenv("SystemDrive"))
# get current Username
user = str(os.getlogin())
user.strip()
# get script path
script_path = (sys.argv[0])
# create FolderPath (Startup Folder)
folder_seg_1 = (boot_drive + '/Users/')
folder_seg_2 = ('/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup')
folder_startup = (folder_seg_1 + user + folder_seg_2)
#check if file exits, if yes copy to Startup Folder
file_name = (ntpath.basename(script_path))
startup_file = (folder_startup + ("/") + file_name)
renamed_file = (folder_startup + ("/") + ("SAMPLE.py"))
# checkfile in Startup Folder
check_path = (os.path.isfile(renamed_file))
if check_path == True:
pass
else:
shutil.copy2(script_path, folder_startup)
os.rename(startup_file, renamed_file)
This script gets your username, your boot drive, the file location of
your file than creates all the paths needed. Like your personal
startup folder. It than checks if there is already a file in the
startup folder if yes it just does nothing and goes on, if not it
copies the file to the startup folder an than renames it (you can use that if you want but you don't need to).
It is not necessary to do an os.getenv("SystemDrive") or os.getlogin(), because os.getenv("AppData") already gets both. So the most direct way of doing it that I know of is this:
path = os.path.join(os.getenv("appdata"),"Microsoft","Windows","Start Menu","Programs","Startup")

How to open a file on app engine patch?

I tried to read a file in a view like this:
def foo(request):
f = open('foo.txt', 'r')
data = f.read()
return HttpResponse(data)
I tried to place the foo.txt in almost every folder in the project but it still returns
[Errno 2] No such file or directory:
'foo.txt'
So does anybody knows how to open a file in app engine patch? Where should i place the files i wish to open? many thanks.
I'm using app-engine-patch 1.1beta1
In App Engine, patch or otherwise, you should be able to open (read-only) any file that gets uploaded with your app's sources. Is 'foo.txt' in the same directory as the py file? Does it get uploaded (what does your app.yaml say?)?
Put './' in front of your file path:
f = open('./foo.txt')
If you don't, it will still work in App Engine Launcher 1.3.4, which could be confusing, but once you upload it, you'll get an error.
Also it seems that you shouldn't mention the file (or its dir) you want to access in app.yaml. I'm including css, js and html in my app this way.
You should try f = open('./foo.txt', 'r')

Categories