Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

django 4.2 - storage options (problem with s3 and template tag) #748

Open
pziewiec opened this issue Nov 25, 2023 · 4 comments
Open

django 4.2 - storage options (problem with s3 and template tag) #748

pziewiec opened this issue Nov 25, 2023 · 4 comments

Comments

@pziewiec
Copy link

@lru_cache
def get_or_create_storage(storage):
    return get_module_class(storage)()

sorl/thumbnail/images.py:23 - storage options parameter is missing

check this way:
https://github.com/django/django/blob/b0ec87b8578147be4357c90eabcd2b916c780810/django/core/files/storage/handler.py#L38C38-L38C38

@emdede
Copy link

emdede commented Sep 26, 2024

For anyone that finds themselves here looking for a solution. This is what I did as a workaround in my project:

# my_app/utils.py
def alias_default_storage(*args):
    from django.core.files.storage import storages

    return storages["default"] # or another key


# settings.py
THUMBNAIL_STORAGE = "my_app.utils.alias_default_storage"

from sorl.thumbnail import images

from my_app.utils import alias_default_storage

images.get_or_create_storage = alias_default_storage

There is also an additional problem when sorl-thumbnail is used in conjunction with filer because filer at the moment has a similar problem. To fix this particular issue there is at least no need to manually patch code but you do have to explicitly set the FILER_STORAGES engine options:

# settings.py

FILER_STORAGES = {
    "public": {
        "main": {
            "ENGINE": "storages.backends.s3.S3Storage",
            # Mirror the OPTIONS kwargs provided to your django storage
            "OPTIONS": {
                "bucket_name": media_bucket_name,
                "querystring_auth": False,
            },
        },
    }
}

@supern8ent
Copy link

Hi, I wanted to chime in here in 2025: I'm ran into the same issue with google cloud storage. sorl-thumbnail 12.11.0 with Django 5.0.4, django-storages 1.14.3, google-cloud-storage 2.17.0.

The {% thumbnail ... %} tag causes this exception when creating a new thumbnail:

ValueError: Cannot determine path without bucket name.

The workaround from @emdede above works.

My storage config:

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
        "OPTIONS": {
            "project_id": "my-project",
            "file_overwrite": False,
            "blob_chunk_size": 5 * 1024 * 256,
            "credentials": ... get secret ...,
            "bucket_name": "my-bucket",
        },
    }
}

Here's the full trace:

ERROR Thumbnail tag failed
Traceback (most recent call last):
  File ".../.venv/lib/python3.11/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 55, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 135, in _render
    thumbnail = get_thumbnail(file_, geometry, **options)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/sorl/thumbnail/shortcuts.py", line 8, in get_thumbnail
    return default.backend.get_thumbnail(file_, geometry_string, **options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/sorl/thumbnail/base.py", line 102, in get_thumbnail
    if settings.THUMBNAIL_FORCE_OVERWRITE or not thumbnail.exists():
                                                 ^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/sorl/thumbnail/images.py", line 127, in exists
    return self.storage.exists(self.name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/storages/backends/gcloud.py", line 247, in exists
    return bool(self.bucket.get_blob(name))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/google/cloud/storage/bucket.py", line 1276, in get_blob
    blob.reload(
  File ".../.venv/lib/python3.11/site-packages/google/cloud/storage/_helpers.py", line 301, in reload
    self.path,
    ^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/google/cloud/storage/blob.py", line 334, in path
    return self.path_helper(self.bucket.path, self.name)
                            ^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/google/cloud/storage/bucket.py", line 1173, in path
    raise ValueError("Cannot determine path without bucket name.")
ValueError: Cannot determine path without bucket name.

@claudep
Copy link
Contributor

claudep commented Mar 22, 2025

It would be great if various issue reporters in this ticket could experiment with the master branch and test the new capability to use a Django storage alias instead of the path to a storage class, as introduced in b348c63
With such a confirmation, we could then push for a new release.

@panizza
Copy link

panizza commented Mar 26, 2025

@claudep there are still issues when serializing/deserializing the storage.
https://github.com/jazzband/sorl-thumbnail/blob/53644ce773d1fac79fa1e1ab6f59ff0df51dae49/sorl/thumbnail/images.py

When the serialize_image_file method is called you serialize the storage path, not the storage alias.
After this happens the deserialize_image_file retrieves the saved storage path and create a new storage without options, leading to errors.

here's my config

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": {
            "location": "private",
            "bucket_name": "media",
            "access_key": "",
            "secret_key": "",
            "endpoint_url": "",
            "default_acl": "private",
            "file_overwrite": False,
            "signature_version": "s3v4",
            "region_name": "auto",
        },
    },
}

get_or_create_storage output is a storage without options

{'_constructor_args': ((), {}), 'cloudfront_signer': None, 'access_key': None, 'secret_key': None, 'security_token': None, 'session_profile': None, 'file_overwrite': True, 'object_parameters': {}, 'bucket_name': None, 'querystr
ing_auth': True, 'querystring_expire': 3600, 'signature_version': None, 'location': '', 'custom_domain': None, 'cloudfront_key_id': None, 'cloudfront_key': None, 'addressing_style': None, 'file_name_charset': 'utf-8', 'gzip': F
alse, 'gzip_content_types': ('text/css', 'text/javascript', 'application/javascript', 'application/x-javascript', 'image/svg+xml'), 'url_protocol': 'https:', 'endpoint_url': None, 'proxies': None, 'region_name': None, 'use_ssl'
: True, 'verify': None, 'max_memory_size': 0, 'default_acl': None, 'use_threads': True, 'transfer_config': <boto3.s3.transfer.TransferConfig object at 0x7ff9b6e26080>, 'client_config': <botocore.config.Config object at 0x7ff9b6e26470>, '_bucket': None, '_connections': <_thread._local object at 0x7ff9b6b7bc90>, '_unsigned_connections': <_thread._local object at 0x7ff9b58b2f20>}

@emdede fix works, but maybe it's better if we serialize the storage name instead of the path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants