Google App Engine No such file or directory: - python

I'm trying to deploy a project to Google App Engine. The main HTML page I render is stored in the /documents/form.html directory of the project. If I run on my local host it finds the file no problem. When I deploy to GAE it gives the below error:
File "/base/data/home/apps/s~andesonchase/1.372703354720880550/main.py", line 4, in <module>
fileHandle = open("documents/form.html", "r")
IOError: [Errno 2] No such file or directory: 'documents/form.html'
I think I need to include it on my app.yaml but I'm not sure on the correct syntax.

I can list three options for you
A) as suggested by the previous poster is to add to app.yaml as either a static_files entry or by making documents a static_dir which would allow access to the files using raw http requests but completely bypassing your handlers in main.py
B) [probably the most kosha] is to access the file with the jinja2 template library as explained here which doesn't require you to add the files explicitly to app.yaml
C) or you could stick with whatever your doing inside main.py at the moment but modify your open statement as follows
import os.path
f = open(os.path.dirname(__file__) + '/documents/form.html')
as explained in this stackoverlflow answer since open works a little differently with appengine

If you want to serve it as a static file add it like this:
Add it to your app.yaml and replace /form with the url you please
- url: /form
static_files: documents/form.html
upload: documents/form.html
If you need to run a script then it's different.

Related

OSError: [Errno 30] Read-only file system in Django on Heroku

I'm using Django 2.0 and Heroku to host the application.
My media directory settings are like
App/settings/production.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static_cdn', 'media_root')
I'm using gTTS to convert text to speech and save .mp3 file in the media directory:
tts_file_name = str(int(time.time())) + '.mp3'
joined_path = os.path.join(settings.MEDIA_ROOT, 'tts')
joined_path_with_file = os.path.join(joined_path, tts_file_name)
# create directory if does not exists
if not os.path.exists(joined_path):
os.makedirs(joined_path)
tts = gTTS(text='Good morning', lang='en')
tts.save(joined_path_with_file)
# tts path to send to template
tts_media_url = os.path.join(settings.MEDIA_URL, 'tts', tts_file_name)
It is working fine on local system as I can change file permissions manually also.
But It is not working on Heroku and giving error:
OSError: [Errno 30] Read-only file system: '/static_cdn'
I tried to locate static_cdn by running heroku shell, but could not even found static_cdn in application path and root path. But it seems to be working as other uploading through form is working perfectly.
using Django model's upload_to is working and even directory is created in static_cdn.
How can I create directory in static_cdn on Heroku the same way Django does using model's upload_to?
Changed MEDIA_ROOT path by removing additional os.path.dirname() and it is working now.
MEDIA_ROOT = os.path.join(BASE_DIR, 'static_cdn', 'media_root')
In my case, this error occurred because I set the STATIC_ROOT = '/static/'
This means it's looking at / root folder of the system and then static, which is obviously read-only,
changing it to STATIC_ROOT = 'static/' fixed my issue.
I'm using gTTS to convert text to speech and save .mp3 file in the media directory
I'm not sure what's causing your immediate error, but this isn't going to work very well on Heroku. Its filesystem is ephemeral: you can write to it, but whatever you write will be lost when the dyno restarts. This happens frequently (at least once per day).
Heroku recommends using a third-party file or object store like Amazon S3 for storing generated files, uploaded files, etc. I recommend gong down this path. There are many Django libraries for using S3, and other services, as storage backends.

Python with open doesn't create new file after deployed at Heroku

I'm working on a python project in which I need to create a new JSON file.It's working locally but when I deploy my app to Heroku the file creation doesn't work.
Here's what I have tried:
From settings.py
APP_ROOT = os.path.dirname(os.path.abspath(__file__)) # refers to application_top
APP_FINALIZED = os.path.join(APP_ROOT, 'finalized')
From app.py
HOME = os.path.join(APP_FINALIZED)
print(HOME)
with open(HOME + '/description_' + str(fid) + '.json', 'w', encoding="utf-8")\
as f:
f.write(json.dumps(data, indent=4, ensure_ascii=False))
Updated: can we write this file directly to the S3 bucket, anyway?
it's working fine locally, but when I deploy it on Heroku the file doesn't create, even it doesn't show any error.
I'll add this as answer as well in case someone elese needs help.
Heroku's file system is (as far as I can remember) read-only.
Please check this answer.

How to open a .txt file in Flask? [duplicate]

This question already has an answer here:
Refering to a directory in a Flask app doesn't work unless the path is absolute
(1 answer)
Closed 5 years ago.
I'm trying to build a website using the Flask framework for Python.
I'm on a Linux Ubuntu server, with Apache2.
On my website, whenever someone enters the URL "/Elv_1.html", I want to open a .txt file, get some values and create a graph using pygal. Here is my code:
#app.route('/river_1.html')
def riv_1():
try:
document = open('temp.txt','r')
temp_list = []
for n in document:
n = n.rstrip('\n')
n = int(n)
temp_list.append(n)
document.close()
graf = pygal.Line(title=u'Tempt last 24h')
graf.x_labels = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
graf.add('Temp', temp_list)
graf = graf.render_data_uri()
return render_template('river_1.html', graf=graf)
except Exception, e:
return str(e)
if __name__ == '__main__':
app.run(debug=True)
The file 'temp.txt' is located in the same directory as the __init__.py file. __init__.py is the Flask app that the code comes from.
When I do this on my computer using localhost to run the server, it works just fine. However, when I upload this to my Linux server and try to enter that specific URL, it shows the following error:
[Error 2] No such file or directory: 'temp.txt'
Any suggestions as to why it doesn't appear to find the file?
Try using the os module when specifying the path to your file. I am asuming you are using a windows pc when runing on localhost?
import os
document_path = os.getcwd()+'temp.txt'
document = open(documnet_path, 'r')
Make sure you are running the server from it's directory. So if you have this structure as shown below, you can't simply open terminal and type server/__init__.py, because you are in your home directory (/home/username/). You need to cd to server and there run ./__init__.py
/home/
username/
server/
__init__.py
temp.txt
Or, if you want to run it from somewhere else, run open the file from os.path.abspath(os.path.dirname(__file__)) + '/temp.txt') (Tested with python 3.5.2)
See python docs for os.path.

Redirecting to the resource file in static directory with Flask

I have a static directory that contains some resources (data files), and I can access the files directly: i.e., http://hello.com/static/dir/abc.pdf. However, I got error with the directory as the address: i.e., http://hello.com/static/dir.
Using flask, I can solve this issue by showing the contents of the directory.
#app.route('/static/<path:url>') #protect
def show(url):
content_dir = app.config['CONTENT_DIR']
directory = "%s/%s/box/%s" % (content_dir, url, url2)
result = []
if os.path.isdir(directory):
for file in os.listdir(directory):
content['url'] = '/static/...
result.append(content)
return render_template("box.html",...)
The issue is that with this route processing, the direct file accessing doesn't work any more as http://hello.com/static/dir/abc.pdf always triggers the show() method.
How can I redirect to the resource file (abc.pdf in the example), without being redirected to the show() method?
In your custom static route, check if the path is a file or a directory. If it's a file, serve it, otherwise show the directory index.
import os
from flask import send_file
path = os.path.join(app.config['CONTENT_DIR'], url, 'box', url2)
if os.path.isfile(path):
return send_file(path)
return render_template('box.html', ...)
Of course, since the path is specified by the url sent by the user, you should check that it's safe first.

IO error for static file in appengine

AppEngine throws the following error:
IOError: [Errno 13] file not accessible: '/home/username/code/appname/csv/master.csv'
The relevant part of the script looks like this:
project_dir = os.path.dirname(__file__)
csv_data = csv.DictReader(open(project_dir+'master.csv','rU'))
The relevant part of the app.yaml looks like this:
handlers:
- url: /csv
static_dir: csv
I get the same error when deleting the handler.
FYI: I do not get the IO error when putting the csv file in the top directory of my app. I need the handler because javascript on my website is sending a get request to the csv file and this does not work for the top-level directory (why?). I could have the csv in the top directory AND the csv directory at the same time but I think there could be a cleaner solution.
Any ideas?
Update your app.yaml static handler to be application_readable.
https://developers.google.com/appengine/docs/python/config/appconfig
application_readable
Optional. By default, files declared in static file handlers are uploaded as static data and are only served to end users, they cannot be read by an application.

Categories

Resources