2

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.

jablok1
  • 21
  • 2
  • I don't have insights into that API, but you can generate and use HMAC credentials for IBM Cloud COS and use them with S3 APIs / SDKs. – data_henrik Sep 23 '21 at 05:08
  • Thanks @data_henrick. I'm not having trouble getting connected even though not using HMAC. The code above puts the file in the bucket, but throws the error and doesn't update the django db. – jablok1 Sep 23 '21 at 12:05

0 Answers0