I'm trying to connect a django app to IBM COS and having trouble. I'm capturing user video and want to save the file to IBM COS and the user info to Postgres also hosted on IBM. I'm able to connect from both the terminal and my app to IBM COS and move files around, but am having trouble getting the default storage configured properly. I'm using django-storages, trying to adapt the AWS configurations for IBM but I must be missing something.
This code will save the file to IBM COS, but makes no entries in the DB. The problem may be in the configuration? Also, I am not able to manually upload a file form the django admin panel - I get a similar traceback. Thanks in advance for any help.
settings.py
# IBM STORAGE CONFIG
IBM_API_KEY_ID = 'IBM_API_KEY_ID'
IAM_SERVICE_ID = 'IAM_SERVICE_ID'
ENDPOINT = 'https://s3.us-east.cloud-object-storage.appdomain.cloud'
IBM_AUTH_ENDPOINT = 'https://iam.bluemix.net/oidc/token'
SERVICE_INSTANCE_ID = 'SERVICE_INSTANCE_ID'
IBM_STORAGE_BUCKET_NAME = 'cloud-object-storage-3u-cos-standard-77w'
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
models.py
class Video(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
videofilename=models.CharField(max_length=500)
videofile=models.FileField(upload_to="video/", null=True, verbose_name="")
def __str__(self):
return str(self.videofile)
views.py
class upload_to_ibm_auto(LoginRequiredMixin, CreateView):
model = Video
context_object_name = 'Videos'
form_class = VideoForm
template_name = 'app_video/upload_to_ibm_auto.html'
success_url = reverse_lazy('video_upload_local')
def form_valid(self, form):
# create connection to IBM
cos_client = ibm_boto3.client(service_name='s3',
ibm_api_key_id=settings.IBM_API_KEY_ID,
ibm_service_instance_id=settings.IAM_SERVICE_ID,
ibm_auth_endpoint=settings.IBM_AUTH_ENDPOINT,
config=Config(signature_version='oauth'),
endpoint_url=settings.ENDPOINT)
# assign variables for upload to IBM
upload_name = str(form.cleaned_data['videofilename'])
local_file_name = 'C:/zjunk/' + str(form.cleaned_data['videofile'])
userid = str(self.request.user.id)
uploadtime=str(datetime.datetime.now())
key = userid + '-' + uploadtime + '-' + upload_name
#key='test'+form.cleaned_data['videofilename']
#local_file_name=form.cleaned_data['videofile']
#Bucket=str('cloud-object-storage-3u-cos-standard-77w')
bucket = settings.IBM_STORAGE_BUCKET_NAME
print(bucket)
try:
cos_client.upload_file(Filename=local_file_name, Bucket=bucket, Key=key)
except Exception as e:
print(Exception, e)
else:
print('File Uploaded to IBM')
return super(upload_to_ibm_auto, self).form_valid(form)
Traceback:
Environment:
Request Method: POST
Request URL: http://localhost:8000/app_video_upload_to_ibm_auto/
Django Version: 3.2.6
Python Version: 3.9.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'drf_spectacular',
'storages',
'app_crm',
'app_video',
'app_library']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\contrib\auth\mixins.py", line 71, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\views\generic\edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\views\generic\edit.py", line 142, in post
return self.form_valid(form)
File "C:\Users\Kord\source\repos\storyline\dev\01\PythonDjangoAppLMSUS2021-08-23-SL-1\app_video\views.py", line 163, in form_valid
return super(upload_to_ibm_auto, self).form_valid(form)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\views\generic\edit.py", line 125, in form_valid
self.object = form.save()
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\forms\models.py", line 468, in save
self.instance.save()
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\base.py", line 763, in save_base
updated = self._save_table(
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\base.py", line 906, in _do_insert
return manager._insert(
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\sql\compiler.py", line 1415, in execute_sql
for sql, params in self.as_sql():
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\sql\compiler.py", line 1358, in as_sql
value_rows = [
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\sql\compiler.py", line 1359, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\sql\compiler.py", line 1359, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\sql\compiler.py", line 1310, in pre_save_val
return field.pre_save(obj, add=True)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\fields\files.py", line 302, in pre_save
file.save(file.name, file.file, save=False)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\db\models\fields\files.py", line 89, in save
self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\core\files\storage.py", line 53, in save
name = self.get_available_name(name, max_length=max_length)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\storages\backends\s3boto3.py", line 585, in get_available_name
return super().get_available_name(name, max_length)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\django\core\files\storage.py", line 87, in get_available_name
while self.exists(name) or (max_length and len(name) > max_length):
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\storages\backends\s3boto3.py", line 457, in exists
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\client.py", line 386, in _api_call
return self._make_api_call(operation_name, kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\client.py", line 677, in _make_api_call
request_dict = self._convert_to_request_dict(
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\client.py", line 723, in _convert_to_request_dict
api_params = self._emit_api_params(
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\client.py", line 752, in _emit_api_params
self.meta.events.emit(
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\hooks.py", line 357, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\hooks.py", line 228, in emit
return self._emit(event_name, kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\hooks.py", line 211, in _emit
response = handler(**kwargs)
File "C:\Users\Kord\source\repos\storyline\dev\01\venv2\lib\site-packages\botocore\handlers.py", line 235, in validate_bucket_name
if not VALID_BUCKET.search(bucket) and not VALID_S3_ARN.search(bucket):
Exception Type: TypeError at /app_video_upload_to_ibm_auto/
Exception Value: expected string or bytes-like object
Thanks again.