I am totally new to this. My Django app is run in Docker. My app allows users to upload files which are stored, followed by executing some functions on the file then generating a new file that the user can download. I’d like to store the initial user-uploaded file and the output-file my django code generates. Here is my code:
models.py:
class TranscribedDocument(models.Model):
id = models.CharField(primary_key=True, max_length = 40)
audio_file = models.FileField(upload_to='ai_transcribe_upload/', null= True)
output_file = models.FileField(null= True)
date = models.DateTimeField(auto_now_add=True, blank = True, null=True)
views.py:
#save uploaded file
if form.is_valid():
uploaded_file = request.FILES['file']
request.session['uploaded_file_name'] = uploaded_file.name
request.session['uploaded_file_size'] = uploaded_file.size#add to models.py
session_id = str(uuid.uuid4())
request.session['session_id'] = session_id
transcribed_doc, created = TranscribedDocument.objects.get_or_create(id=session_id)
transcribed_doc.audio_file = uploaded_file
transcribed_doc.save()
request.session['uploaded_file_path'] = transcribed_doc.audio_file.path
#generate new file
with open(file_location, 'r', encoding=charenc) as f:
file_data = f.read()##
transcribed_doc, created = TranscribedDocument.objects.get_or_create(
id = request.session['session_id']
)
transcribed_doc.output_file = transcript_path
transcribed_doc.date = timezone.now()
transcribed_doc.save()
settings.py:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "db", # set in docker-compose.yml
"PORT": 5432, # default postgres port
}
}
AWS_ACCESS_KEY_ID = 'key_id'
AWS_SECRET_ACCESS_KEY = 'secret_key_id'
AWS_STORAGE_BUCKET_NAME = 'name'
AWS_DEFAULT_ACL = 'public-read' #change to private
AWS_S3_ENDPOINT_URL = 'https://nyc3.digitaloceanspaces.com/' # Make sure nyc3 is correct
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400'
}
AWS_MEDIA_LOCATION = 'media/'
PUBLIC_MEDIA_LOCATION = 'media/'
MEDIA_URL = '%s%s' % (AWS_S3_ENDPOINT_URL, AWS_MEDIA_LOCATION)
DEFAULT_FILE_STORAGE = 'mysite.storage_backends.MediaStorage'
djangoProjects/mysite/storage_backends.py:
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
bucket_name = 'media'
location = ''
requirements.txt:
whitenoise==6.1.0
django-storages[s3]==1.14.2
gunicorn==20.1.0
The existing code above used to save it DO spaces is what I found online however it doesn’t work and instead I see this error report when I run docker-compose logs
:
Traceback (most recent call last):
web-1 | File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
web-1 | response = get_response(request)
web-1 | ^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
web-1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/decorators.py", line 134, in _wrapper_view
web-1 | response = view_func(request, *args, **kwargs)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/code/transcribe/views.py", line 37, in transcribeSubmit
web-1 | transcribed_doc.save()
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 814, in save
web-1 | self.save_base(
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 877, in save_base
web-1 | updated = self._save_table(
web-1 | ^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 981, in _save_table
web-1 | values = [
web-1 | ^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 985, in <listcomp>
web-1 | (getattr(self, f.attname) if raw else f.pre_save(self, False)),
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/fields/files.py", line 317, in pre_save
web-1 | file.save(file.name, file.file, save=False)
web-1 | File "/usr/local/lib/python3.11/site-packages/django/db/models/fields/files.py", line 93, in save
web-1 | self.name = self.storage.save(name, content, max_length=self.field.max_length)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/django/core/files/storage/base.py", line 38, in save
web-1 | name = self._save(name, content)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/storages/backends/s3.py", line 494, in _save
web-1 | obj.upload_fileobj(content, ExtraArgs=params, Config=self.transfer_config)
web-1 | File "/usr/local/lib/python3.11/site-packages/boto3/s3/inject.py", line 731, in object_upload_fileobj
web-1 | return self.meta.client.upload_fileobj(
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/boto3/s3/inject.py", line 642, in upload_fileobj
web-1 | return future.result()
web-1 | ^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/s3transfer/futures.py", line 103, in result
web-1 | return self._coordinator.result()
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/s3transfer/futures.py", line 266, in result
web-1 | raise self._exception
web-1 | File "/usr/local/lib/python3.11/site-packages/s3transfer/tasks.py", line 139, in __call__
web-1 | return self._execute_main(kwargs)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/s3transfer/tasks.py", line 162, in _execute_main
web-1 | return_value = self._main(**kwargs)
web-1 | ^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/s3transfer/upload.py", line 764, in _main
web-1 | client.put_object(Bucket=bucket, Key=key, Body=body, **extra_args)
web-1 | File "/usr/local/lib/python3.11/site-packages/botocore/client.py", line 565, in _api_call
web-1 | return self._make_api_call(operation_name, kwargs)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/botocore/client.py", line 1021, in _make_api_call
web-1 | raise error_class(parsed_response, operation_name)
web-1 | botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: None
web-1 | [02/May/2024 12:17:21] "POST /transcribe/ HTTP/1.1" 500 159369
If there is an easier/safer alternative to django-storages please suggest.