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

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.

Related

creating/deleting folders in runtime using heroku/django

I have developed a Django app where I am uploading a file, doing some processing using a project folder name media.
Process:
user uploads a csv file, python code treats the csv data by creating temp folders in Media folder. After processing is complete, these temp folders are deleted and processed data is downloaded through browser.
I am using the below lines of code to make and delete temp file after processing
temp = 'media/temp3'
os.mkdir(temp)
shutil.copyfile('media/' + file_name, temp + '/' + file_name)
shutil.rmtree(temp, ignore_errors=True)
To set the media root, I used the below lines in settings.py which I am sure I am not using in other parts of the code.
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = "/media/"
Everything works fine when I run the app on local host. but as soon as i deployed it to heroku, it seems like these folders were not created/not found.
I am looking for:
Either a solution to create, read and delete folders/files in runtime using heroku,
or
a better way to manage files/folders in runtime.

Django can't find static files after changing name of folder in project path

I have a Django project that I have been working on and I want to change the name of a folder in the project's file path. My current path to my project looks like this:
/Users/user/Documents/Python/Django Projects/ProjectName/
I want to change the project path to:
/Users/user/Documents/Python/Django_Projects/ProjectName/
When I do this change I get the following error message:
OSError at /
[Errno 2] No such file or directory:
'/Users/user/Documents/Python/Django Projects/ProjectName/assets'
In my settings.py file I have this:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'assets'), )
In the request META the PWD value is unchanged:
PWD '/Users/user/Documents/Python/Django Projects/ProjectName'
I'm fairly new to programming so I apologise for asking such a simple question, but any help would be greatly appreciated.
Thanks

django app multiple hard drives [Errno 18] Invalid cross-device link

I have a Django app on a Debian server and my current site_media directory on the current disk is full. So I want to upload files On a second disk. The path on server is /disk :
obj = form.save(commit=False)
obj.user_id = self.request.user.pk
obj.save()
initial_path = obj.file.path
print(initial_path)
new = settings.MEDIA_ROOT_NEW + obj.file.name
print(new)
os.rename(initial_path,new)
shutil.move(initial_path, new)
and in my settings.py I have:
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'site_media/')
MEDIA_ROOT_NEW = '/disk/site_media/'
still I get error:
django [Errno 18] Invalid cross-device link
Any ideas?
os.rename() may fail across different file systems.
The operation may fail on some Unix flavors if src and dst are on different filesystems.
shutil.move() should work
If the destination is on the current filesystem, then os.rename() is used. Otherwise, src is copied (using shutil.copy2()) to dst and then removed.
but you've got a os.rename(initial_path,new) just before your shutil.move(initial_path, new). Remove the first os.rename() and it should work.

Django - Permission denied to open media in production server (Azure)

Now i am working on production server (AzureWebsites) and i want to open my .txt files.
This is the tree that i used to save my stopwords.txt
-App
-media
-App
stopwords.txt
-static
-templates
settings.py
MEDIA_ROOT = path.join(PROJECT_ROOT, 'media').replace('\\', '/')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'
I want to open the text file using this command
handle = open('/media/stopwords.txt', 'r+')
var = handle.read()
This is the error i got when run my app
[Errno 13] Permission denied: '/media/stopwords.txt'
and when i try to modify the open statements with this
handle = open(settings.MEDIA_ROOT + 'stopwords.txt', 'r+')
i got this error
[Errno 2] No such file or directory: 'D:/home/site/wwwroot/mediastopwords.txt'
Can anyone please help fix this problem?
Try handle = open(settings.MEDIA_ROOT + '/stopwords.txt', 'r+')
According to your tree stopwords is stored under /media/App/stopwords.txt
So to open it you need:
handle = open(settings.MEDIA_ROOT + '/App/stopwords.txt', 'r+')

Google App Engine No such file or directory:

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.

Categories

Resources