[Django]-Are there any Django packages to create signed urls for Google Cloud Storage resources?

2👍

This is a working code in django 1.11 with python3.5.

import os
from google.oauth2 import service_account
from google.cloud import storage


class CloudStorageURLSigner(object):
    @staticmethod
    def get_video_signed_url(bucket_name, file_path):
        creds = service_account.Credentials.from_service_account_file(
            os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
        )
        bucket = storage.Client().get_bucket(bucket_name)
        blob = bucket.blob(file_path)
        signed_url = blob.generate_signed_url(
            method='PUT',
            expiration=1545367030, #epoch time
            content_type='audio/mpeg', #change_accordingly
            credentials=creds
        )
        return signed_url

1👍

Yes, take a look at google-cloud-storage

Installation:

pip install google-cloud-storage

Also, make sure to refer to API Documentation as you need more things.

Hope it helps!

1👍

I ended up solving this problem by using to_representation in serializers.py:

from google.cloud.storage import Blob
client = storage.Client()
bucket = client.get_bucket('myBucket')

    def to_representation(self, value):
        try:
            blob = Blob(name=value.name, bucket=bucket)
            signed_url = blob.generate_signed_url(expiration=datetime.timedelta(minutes=5))
            return signed_url
        except ValueError as e:
            print(e)
            return value

0👍

Extending @Evan Zamir’s answer, instead of reassigning client and bucket you can get them from Django’s default_storage (this will save time since these are already available).

This is in settings.py

from datetime import timedelta
from google.oauth2 import service_account

GS_CREDENTIALS = service_account.Credentials.from_service_account_file('credentials.json')
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
GS_BUCKET_NAME = "my-bucket"
GS_EXPIRATION = timedelta(seconds=60)

In serializers.py

from django.core.files.storage import default_storage
from google.cloud.storage import Blob
from rest_framework import serializers

class SignedURLField(serializers.FileField):
    def to_representation(self, value):
        try:
            blob = Blob(name=value.name, bucket=default_storage.bucket)
            signed_url = blob.generate_signed_url(expiration=default_storage.expiration)
            return signed_url
        except ValueError as e:
            print(e)
            return value

You can use this class in your serializer like this,

class MyModelSerializer(serializers.ModelSerializer):
    file = SignedURLField()

Note: Do not provide GS_DEFAULT_ACL = 'publicRead' if you want signed URLs as it creates public URLs (that do not expire)

👤Mujeeb

Leave a comment