Настройка Django и Google Cloud Storage?

Я не, используя Appengine.

У меня есть обычное приложение Django с ванилью, работающее на виртуальной машине. Я хочу использовать Google Cloud Storage для обслуживания своих статических файлов, а также для загрузки/обслуживания моих медиафайлов.

У меня есть ведро.

Как связать приложение Django с моим ведром? Я пробовал django-storages. Это может сработать, но что мне нужно сделать, чтобы подготовить мое ведро для использования моим приложением django? И какая базовая конфигурация мне нужна в настройках Django?

Текущие настройки:

# Google Cloud Storage
# http://django-storages.readthedocs.org/en/latest/backends/apache_libcloud.html
LIBCLOUD_PROVIDERS = {
    'google': {
        'type'  : 'libcloud.storage.types.Provider.GOOGLE_STORAGE',
        'user'  : <I have no idea>,
        'key'   : <ditto above>,
        'bucket': <my bucket name>,
    }
}

DEFAULT_LIBCLOUD_PROVIDER = 'google'
DEFAULT_FILE_STORAGE = 'storages.backends.apache_libcloud.LibCloudStorage'
STATICFILES_STORAGE = 'storages.backends.apache_libcloud.LibCloudStorage'

Ответ 1

Django-хранилища имеют бэкэнд для облачного хранилища Google, но он не документирован, я понял, что смотрю в репо. Он работал с этой настройкой:

DEFAULT_FILE_STORAGE = 'storages.backends.gs.GSBotoStorage'
GS_ACCESS_KEY_ID = 'YourID'
GS_SECRET_ACCESS_KEY = 'YourKEY'
GS_BUCKET_NAME = 'YourBucket'
STATICFILES_STORAGE = 'storages.backends.gs.GSBotoStorage'

Чтобы получить YourKEY и YourID, вы должны создать клавиши Interoperability на вкладке настроек.

Надеюсь, что это поможет, и вам не нужно учиться этому трудно:)

А в случае, если вы еще этого не сделали, зависимости:

pip install django-storages
pip install boto

Ответ 2

Джанго-хранилища, по сути, жизнеспособная альтернатива. Вы должны быть осторожны с бэкэндом Google Cloud, хотя метод url() который он предоставляет, вызывает ненужные HTTP-вызовы в Google. (Django вызывает .url() при рендеринге статических файлов, например).

https://github.com/jschneier/django-storages/issues/491

settings.py

    DEFAULT_FILE_STORAGE = 'config.storage_backends.GoogleCloudMediaStorage'
    STATICFILES_STORAGE = 'config.storage_backends.GoogleCloudStaticStorage'
    GS_PROJECT_ID = '<google-cloud-project-id>'
    GS_MEDIA_BUCKET_NAME = '<name-of-static-bucket>'
    GS_STATIC_BUCKET_NAME = '<name-of-static-bucket>'
    STATIC_URL = 'https://storage.googleapis.com/{}/'.format(GS_STATIC_BUCKET_NAME)
    MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_MEDIA_BUCKET_NAME)

storage_backends.py

    """
    GoogleCloudStorage extensions suitable for handing Django's
    Static and Media files.

    Requires following settings:
    MEDIA_URL, GS_MEDIA_BUCKET_NAME
    STATIC_URL, GS_STATIC_BUCKET_NAME

    In addition to
    https://django-storages.readthedocs.io/en/latest/backends/gcloud.html
    """
    from django.conf import settings
    from storages.backends.gcloud import GoogleCloudStorage
    from storages.utils import setting
    from urllib.parse import urljoin


    class GoogleCloudMediaStorage(GoogleCloudStorage):
        """GoogleCloudStorage suitable for Django Media files."""

        def __init__(self, *args, **kwargs):
            if not settings.MEDIA_URL:
                raise Exception('MEDIA_URL has not been configured')
            kwargs['bucket_name'] = setting('GS_MEDIA_BUCKET_NAME', strict=True)
            super(GoogleCloudMediaStorage, self).__init__(*args, **kwargs)

        def url(self, name):
            """.url that doesn't call Google."""
            return urljoin(settings.MEDIA_URL, name)


    class GoogleCloudStaticStorage(GoogleCloudStorage):
        """GoogleCloudStorage suitable for Django Static files"""

        def __init__(self, *args, **kwargs):
            if not settings.STATIC_URL:
                raise Exception('STATIC_URL has not been configured')
            kwargs['bucket_name'] = setting('GS_STATIC_BUCKET_NAME', strict=True)
            super(GoogleCloudStaticStorage, self).__init__(*args, **kwargs)

        def url(self, name):
            """.url that doesn't call Google."""
            return urljoin(settings.STATIC_URL, name)

Примечание. Проверка подлинности по умолчанию выполняется с помощью переменной среды GOOGLE_APPLICATION_CREDENTIALS.

https://cloud.google.com/docs/authentication/production#setting_the_environment_variable

Ответ 3

Итак, это в основном будет работать. (С помощью этой библиотеки и настроек).

Трюк, чтобы заставить его работать, знает, где получить параметры 'user' и 'key' для libcloud.

В Google Cloud Console > Storage нажмите Settings. Затем нажмите правую вкладку под названием Interoperability. На этой панели есть одиночная кнопка, которая говорит что-то вроде Enable Interoperability. Нажмите на нее.

Voila! Теперь у вас есть имя пользователя и ключ.


Примечание. Не используйте django-storages из pypi. Он не обновлялся и не работает с недавними выпусками Django.

Используйте эту версию:

pip install -e 'git+https://github.com/jschneier/django-storages.git#egg=django-storages'


Изменить: Если вы хотите использовать обратный прокси, вы можете рассмотреть мою слегка измененную версию. https://github.com/jschneier/django-storages/compare/master...halfnibble:master

Описание: При определенных обстоятельствах может потребоваться загрузка файлов с использованием обратного прокси. Это может быть использовано для облегчения ошибок запроса перекрестного происхождения.

Этот небольшой PR позволяет разработчику установить опцию LIBCLOUD_PROXY_URL в settings.py.

Пример использования

# Apache VirtualHost conf
ProxyPass /foo http://storage.googleapis.com
ProxyPassReverse /foo http://storage.googleapis.com


# settings.py
LIBCLOUD_PROXY_URL = '/foo/'

Ответ 4

Так как я не могу комментировать ответ Алана Вагнера, вот дополнение.

Если вы используете python3, вы можете получить эту ошибку,

...
ImportError: No module named 'google_compute_engine'

Если это так, вам нужно будет установить google-compute-engine. Файл /etc/boto.cfg сообщает python использовать версию библиотеки 2.7. Вам нужно будет запустить следующую строку для регенерации /etc/boto.cfg.

python3 -c "from google_compute_engine.boto.boto_config import BotoConfig; BotoConfig()"

Еще одна ошибка, которую вы можете поразить,

...
File "/app/venv/lib/python3.4/site-packages/boto/gs/connection.py", line 95, in create_bucket
    data=get_utf8_value(data))
File "/app/venv/lib/python3.4/site-packages/boto/s3/connection.py", line 656, in make_request
    auth_path = self.calling_format.build_auth_path(bucket, key)
File "/app/venv/lib/python3.4/site-packages/boto/s3/connection.py", line 94, in build_auth_path
    path = '/' + bucket
TypeError: Can't convert 'bytes' object to str implicitly

Я сделал запрос pull, чтобы исправить это. Вы можете использовать мое репо в качестве зависимости от пипса, если хотите, пока он не будет слит.

Я постараюсь сохранить это репо в актуальном состоянии. Я установил ветвь develop по умолчанию как защищенную. Я единственный, кто может совершать/одобрять запросы на слияние. Я также сделал только один коммит.

Вам нужно будет установить google-compute-engine и запустить эту строку выше, прежде чем вы сможете установить/создать мое репозитование boto.

Ответ 5

В последней версии ключ доступа и идентификатор ключа изменены на файл учетной записи службы. И мы хотим использовать корзину с 2 static папками и media как локальный сервер. Ниже приведены конфиги обновления:

Создайте файл, подобный gcloud_storages.py:


"""
Modify django-storages for GCloud to set static, media folder in a bucket
"""
from django.conf import settings
from storages.backends.gcloud import GoogleCloudStorage


class GoogleCloudMediaStorage(GoogleCloudStorage):
    """
    GoogleCloudStorage suitable for Django Media files.
    """

    def __init__(self, *args, **kwargs):
        kwargs['location'] = 'media'
        super(GoogleCloudMediaStorage, self).__init__(*args, **kwargs)


class GoogleCloudStaticStorage(GoogleCloudStorage):
    """
    GoogleCloudStorage suitable for Django Static files
    """

    def __init__(self, *args, **kwargs):
        kwargs['location'] = 'static'
        super(GoogleCloudStaticStorage, self).__init__(*args, **kwargs)

Используйте аргумент location для установки местоположения статических медиа файлов в корзине.

В settings.py

from google.oauth2 import service_account
...

GOOGLE_APPLICATION_CREDENTIALS = '/path/service-account.json'
DEFAULT_FILE_STORAGE = 'app.gcloud_storages.GoogleCloudMediaStorage'
STATICFILES_STORAGE = 'app.gcloud_storages.GoogleCloudStaticStorage'
GS_BUCKET_NAME = 'name-of-bucket'
GS_PROJECT_ID = 'project-id'
GS_DEFAULT_ACL = 'publicRead'
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
    GOOGLE_APPLICATION_CREDENTIALS
)