creating/deleting folders in runtime using heroku/django - python

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.

Related

Serving CHANGING static django files in production

I need to serve a static file that has a changing name. This works fine with DEBUG = True, but immediately breaks with DEBUG = False. I'm currently using Whitenoise to serve files in production, and tried executing collectstatic after the filename changes, but that didn't help. Any advice is appreciated
Edit: This is how the filename is changed
newname = 'myfile' + str(random.randint(0, 999999)) + '.css'
newpath = os.path.join(current_dir, ('../staticfiles/stuff/css/' + newname))
os.rename(r'{}'.format(filepath), r'{}'.format(newpath))
I can't quite give full context for why I need this file's name to change

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.

Content from folder on a server

I am working with a python script on a server with the following hierarchy:
DreamteamPy (folder)
pictest.py
assets (folder)
pictures (folder)
31.jpg
picture2.jpg
picture3.jpg
The complete path of the python file is
http://www.cytosine.nl/~owe4_pg3/Rogier/DreamteamPy/pictest.py
And one of the pictures:
http://www.cytosine.nl/~owe4_pg3/Rogier/DreamteamPy/assets/pictures/31.jpg
How can I get all of the files in the pictures folder?
I've tried things like
import os
def index():
filelist=[]
path= "http://www.cytosine.nl/~owe4_pg3/Rogier/DreamteamPy/assets/pictures"
for filename in os.listdir(path):
filelist.append(filename)
but to no avail.
What you call is path isn't a path but a HTTP URL. os.listdir() needs a path on the local file system. Which in your case most likely is something like /home/owe4_pg3/html/Rogier/DreamteamPy/assets/pictures unless it is not a typical Linux installation where a web server is configured to map ~username at the start of the path part of an URL to /home/username/html.
os.listdir() already returns a list, so it doesn't make much sense to copy the elements one by one into another list.
import os
PICTURES_PATH = '/home/owe4_pg3/html/Rogier/DreamteamPy/assets/pictures'
def index():
filenames = os.listdir(PICTURES_PATH)

Automate uploading files in django admin

I have a database model that in the Django model all I need to do is upload an image file to a new database record. Is there anyway I can automate this as I have a lot of images to upload? All images will come from a folder on my computer and each picture will be added to a new database record. All help is appreciated. Thanks
Just run a simple script to save files stored in a particular folder
from django.core.files import File
class MyModel(models.Model):
picture=models.ImageField()
MyModel.picture.save('abc.png', File(open('/tmp/pic.png', 'r')))
To do this for all files in a directory -
BASE_PATH = '/home/somefolder'
files = os.listdir(BASE_PATH)
for file in files:
MyModel.picture.save(file, File(open(os.path.join(BASE_PATH, file), 'r')))

Categories

Resources