FILE (.json) NOT FOUND - python

This is my directory where i have activated a virtual environment:
I'm working on a flask project to create a rest API, and I have a JSON credential file (google vision file), but when I run the code it says file not found even if it's in the same directory. I've activated a virtualenv for this particular project. mainone.py is the code I'm trying to run.
This is the error I am getting:
"File {} was not found.".format(filename)
google.auth.exceptions.DefaultCredentialsError: File date_scanner.json was not found.
And this is the code block where I am using accessing the particular file:
from flask import Flask,request,jsonify
import os,io,re,glob,base64
from google.cloud import vision
from google.cloud.vision import types
from PIL import Image
os.environ['GOOGLE_APPLICATION_CREDENTIALS']=r'date_scanner.json'
client=vision.ImageAnnotatorClient()

This is likely because the "working folder" of the Python process is not the same as where the file is located. There is a small (albeit convoluted) way to generate filenames which will always work:
Use __file__ to get the filename of the Python file where this is called.
Strip the filename from that path using os.path.dirname
Append the filename that you want to open using os.path.join
from os.path import dirname, join
def get_filename(filename):
here = dirname(__file__)
output = join(here, filename)
return output
Some food for thought
However, in this case there is something you should be careful about: The file contains security credentials and should not live in your source code. So while the above example will solve the immediate problem, the security of this should be addressed.
The best way for this is to externalise the filename of the credentials file into a config file. Say, for example you would use a .ini file as config file, you could have something like this in your code somewhere:
config = configparser.ConfigParser()
config.read('config.ini')
vision_creds_file = config.get('google_vision', 'filename')
and then place the following into config.ini:
[google_vision]
filename = /path/to/filename.json
This still requires you to place the config.ini file somewhere which should be documented in your application, as you still cannot add this to the source code (maybe a sample file with defaults).

Related

Regarding file io in Python

I mistakenly, typed the following code:
f = open('\TestFiles\'sample.txt', 'w')
f.write('I just wrote this line')
f.close()
I ran this code and even though I have mistakenly typed the above code, it is however a valid code because the second backslash ignores the single-quote and what I should get, according to my knowledge is a .txt file named "\TestFiles'sample" in my project folder. However when I navigated to the project folder, I could not find a file there.
However, if I do the same thing with a different filename for example. Like,
f = open('sample1.txt', 'w')
f.write('test')
f.close()
I find the 'sample.txt' file created in my folder. Is there a reason for the file to not being created even though the first code was valid according to my knowledge?
Also is there a way to mention a file relative to my project folder rather than mentioning the absolute path to a file? (For example I want to create a file called 'sample.txt' in a folder called 'TestFiles' inside my project folder. So without mentioning the absolute path to TestFiles folder, is there a way to mention the path to TestFiles folder relative to the project folder in Python when opening files?)
I am a beginner in Python and I hope someone could help me.
Thank you.
What you're looking for are relative paths, long story short, if you want to create a file called 'sample.txt' in a folder 'TestFiles' inside your project folder, you can do:
import os
f = open(os.path.join('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
Or using the more recent pathlib module:
from pathlib import Path
f = open(Path('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
But you need to keep in mind that it depends on where you started your Python interpreter (which is probably why you're not able to find "\TestFiles'sample" in your project folder, it's created elsewhere), to make sure everything works fine, you can do something like this instead:
from pathlib import Path
sample_path = Path(Path(__file__).parent, 'TestFiles', 'sample1.txt')
with open(sample_path, "w") as f:
f.write('test')
By using a [context manager]{https://book.pythontips.com/en/latest/context_managers.html} you can avoid using f.close()
When you create a file you can specify either an absolute filename or a relative filename.
If you start the file path with '\' (on Win) or '/' it will be an absolute path. So in your first case you specified an absolute path, which is in fact:
from pathlib import Path
Path('\Testfile\'sample.txt').absolute()
WindowsPath("C:/Testfile'sample.txt")
Whenever you run some code in python, the relative paths that will be generate will be composed by your current folder, which is the folder from which you started the python interpreter, which you can check with:
import os
os.getcwd()
and the relative path that you added afterwards, so if you specify:
Path('Testfiles\sample.txt').absolute()
WindowsPath('C:/Users/user/Testfiles/sample.txt')
In general I suggest you use pathlib to handle paths. That makes it safer and cross platform. For example let's say that your scrip is under:
project
src
script.py
testfiles
and you want to store/read a file in project/testfiles. What you can do is get the path for script.py with __file__ and build the path to project/testfiles
from pathlib import Path
src_path = Path(__file__)
testfiles_path = src_path.parent / 'testfiles'
sample_fname = testfiles_path / 'sample.txt'
with sample_fname.open('w') as f:
f.write('yo')
As I am running the first code example in vscode, I'm getting a warning
Anomalous backslash in string: '\T'. String constant might be missing an r prefix.
And when I am running the file, it is also creating a file with the name \TestFiles'sample.txt. And it is being created in the same directory where the .py file is.
now, if your working tree is like this:
project_folder
-testfiles
-sample.txt
-something.py
then you can just say: open("testfiles//hello.txt")
I hope you find it helpful.

Create local files with python in Django

I want to create files with the extension .txt, .csv, .bin, etc. so the ideal would be with import os I think or if there is some other better way.
But I don't want to save those in the DB they are to consult the once or sporadically, that is, locally are uploaded to the server and then it is replaced and that's it.
In a simple way, I create the files I need, upload them and replace them when I need something that will not be so common.
The directory for these local files would be /app/files/.
I managed to create files using directory path, something like
imports
def createFile (self, my_data, nameFile):
directory = "./my_app/folder/" + nameFile + ".txt" # PATH directory
my_File = open (directory, "w")
my_File.write (my_data)
my_File.close ()
return true
In itself the important thing is import os and write well the directory where the file will be created. No need to modify anything else.
In the Django documentation I saw something in the import of some classes but in my case this was enough, on the other hand now that I write this answer from django.core.files import File which as seen is the equivalent of import os
I tried to use these
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.core.files.storage import FileSystemStorage
As I do not have time and I had problems with these, I went with the easy
PS: maybe then use from django.core.files import File instead of import os as it seems to be the same, if so I update the answer.

What is the standard way to use Python module os to specify the paths for third parties?

(I'm not used to writing python programs for other users to use, so hopefully this question is appropriate.)
My users will download a file generic_file.csv and let's assume that this file will be saved in the "current directory".
So, I write a python script named reader.py
#!/usr/bin/env python
from __future__ import (print_function, absolute_import)
import os
import csv
import random
import string
cd_path = os.getcwd() # return path of current directory
filename = 'generic_file.csv' # filename 'test_enigma.csv'
filepath = os.path.join(os.getcwd(), filename) # returns path to open fname
print(filepath)
Now, if the user runs this in the terminal with python reader.py, it should output the name of the file, ONLY IF the file was saved in the current directory.
That's inconvenient. Most users will just download the file, and they would like reader.py to change to the subdirectory Downloads and read generic_file.csv from that directory.
(1) How does one use os.chdir() to work for every user?
(2) What is the standard way to do this if I was writing third-party software? I imagine I would have the user download the specific CSV file and Python script together.
If you are looking to get the path name of User A's download file, you can do os.path.expanduser('~/Downloads'). This will return /Users/A/Downloads

Where should I place a config.txt in my python project

The project folder hierarchy looks like
ProjectName
->src
->Project.sikuli
->myFile.py
->config.txt
Now, I have all the settings variables being stores in my config.txt and I'm using ConfigParser to fetch the values from it. The reason why I'm using this config file here is that, when this sikuli script is moved to another machine for running I can just change the values in it (like paths, username, password) rather than editing the main python script 'myFile.py'.
But the issue I'm encountering now is that I don't want the config file to be placed some where outside the project so that in my script when I try to fetch the values from it, I don't have to mention the absolute path again in the myFile.txt like:
configParser = ConfigParser.RawConfigParser()
configfilePath = r'D:\MyWorkspace\ProjectName\src\Project.sikuli\config.txt'
Instead I want to have the relative path here so that while migrating the project from machine to machine I don't have to do any manipulations in the main script 'myFile.py'
So what I'm trying to achieve is like:
I should be able to refer the config.txt file by giving it's relative path:
configfilePath = r'D:\MyWorkspace\ProjectName\src\Project.sikuli\config.txt'
If it's going to be kept in the same folder as myFile.py, then in that Python script you could use something like this:
configfilePath = os.path.join(os.path.dirname(__file__), 'config.txt')
The best way to do this is to put the file inside your .sikuli bundle, just as you have done in your example, and then get the path to your file like this:
configFilePath = os.path.join(getBundlePath(), 'config.txt')
I know you can fetch variables and value from a python file by importing it...
import config
I would put it in the root repertory of the project
First, get the path of the currently executed python script:
myPath = os.path.abspath(os.path.dirname(sys.argv[0]))
and then do a join of myPath and 'config.txt'
configfilePath = os.path.join(myPath, 'config.txt')

Write to new non-existent file in same directory, Python 2.7

I'm trying to read a document and write it into a new file (that doesn't exist) in the same directory as the read file
An example would be
test_infile='/Users/name/Desktop/test.txt'
in_file=open(test_infile,'r')
data=in_file.readlines()
out_file=open('test_outfile.csv','w')
out_file should create a new file called test_outfile.csv in the directory /Users/name/Desktop/test_outfile.csv
I worked with the os module and got
def function(test):
import os
in_file=open(test,'r')
dir,file=os.path.split(test)
temp=os.path.join('output.csv')
out_file=open('output.csv','w')
test_file='/Users/name/Desktop/test.txt'
function(test_file)
it runs but nothing is created ?
Use the os.path.split function to split the directory path from the file name, and then the os.path.join function to stitch path constituents together:
import os
dir, file = os.path.split(test_infile)
out_file_name = os.path.join(dir, 'test_outfile.csv')
Please make sure you read the documentation of these functions, and the os.path module in general, since it's very useful.

Categories