How to save media files to Heroku local storage with Django?

Question:

Im having a Django REST app with React for client. Im recording a file with React and sending in to Django. When i save it i modify it with ffmpeg and save it again in the same folder with a new name, the ffmpeg command looks like this:

os.system(f"ffmpeg -i {audio_path} -ac 1 -ar 16000 {target_path}")

Because i need a path for my audio both for opening and saving, i can’t use cloud stores like "Bucket S3, Cloudinary etc.". And the fact that im using it only for a few seconds and then deleting it makes Heroku (the app is deployed there) the perfect place to save it non-persistent. The problem is that the file isn’t getting saved in my library with media files. It saves in the postgre db but doesn’t in my filesystem and when i try to access it my program returns that there isn’t a file with that name. My question is How can i save media files in Heroku file system and how to access them?

settings.py

MEDIA_ROOT = os.path.join(BASE_DIR,'EmotionTalk/AI_emotion_recognizer/recordings')
MEDIA_URL = '/'

urls.py

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('EmotionTalk.emotion_talk_app.urls')),
path('auth/', include('EmotionTalk.auth_app.urls')),
path('api-token-auth/', views.obtain_auth_token),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

views.py

    def post(self, request):
    file_serializer = RecordingSerializer(data=request.data)

    if file_serializer.is_valid():
        file_serializer.save()

        file_name = file_serializer.data.get('recording')
        owner_id = file_serializer.data.get('owner_id')

        current_emotions_count = len(Profile.objects.get(user_id=owner_id).last_emotions)

        print(file_name)
        recognize_emotion.delay(file_name, owner_id)

        return Response({
            'data': file_serializer.data,
            'current_emotions_count': current_emotions_count
        }, status=status.HTTP_201_CREATED)

    return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

tasks.py

def parse_arguments(filename):
import argparse
parser = argparse.ArgumentParser()

new_filename = filename.lstrip('v')

parser.add_argument("audio_path")
parser.add_argument("target_path")

args = parser.parse_args([f'EmotionTalk/AI_emotion_recognizer/recordings/{filename}',
                          f'EmotionTalk/AI_emotion_recognizer/recordings/{new_filename}'])
audio_path = args.audio_path
target_path = args.target_path

if os.path.isfile(audio_path) and audio_path.endswith(".wav"):
    if not target_path.endswith(".wav"):
        target_path += ".wav"
    convert_audio(audio_path, target_path)
    return target_path
else:
    raise TypeError("The audio_path file you specified isn't appropriate for this operation")

parse_arguments is called from recognize_emotion

Asked By: Diyan Kalaydzhiev

||

Answers:

I was using two dynos, one guinicorn and second celery. It appears that every dyno in heroku is using its own file system, so you can’t save files on one dyno and open them by another.

Answered By: Diyan Kalaydzhiev
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.