Skip to content

Commit

Permalink
support all blobstorage settings
Browse files Browse the repository at this point in the history
  • Loading branch information
nitely committed Feb 11, 2019
1 parent efcad7f commit a6ea342
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
31 changes: 29 additions & 2 deletions docs/backends/azure.rst
Expand Up @@ -76,8 +76,6 @@ Set the default storage (i.e: for media files) and the static storage

The following settings are available:

is_emulated = setting('AZURE_EMULATED_MODE', False)

``AZURE_ACCOUNT_NAME``

This setting is the Windows Azure Storage Account name, which in many cases
Expand Down Expand Up @@ -125,3 +123,32 @@ The following settings are available:
``AZURE_LOCATION``

Default location for the uploaded files. This is a path that gets prepended to every file name.

``AZURE_EMULATED_MODE``

Whether to use the emulator. Defaults to False.

``AZURE_ENDPOINT_SUFFIX``

The host base component of the url, minus the account name. Defaults
to Azure (core.windows.net). Override this to use the China cloud
(core.chinacloudapi.cn).

``AZURE_CUSTOM_DOMAIN``

The custom domain to use. This can be set in the Azure Portal. For
example, 'www.mydomain.com'.

This is also useful to send request to a custom host:port when using
the emulator.

``AZURE_CONNECTION_STRING``

If specified, this will override all other parameters.
See http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/
for the connection string format.

``AZURE_TOKEN_CREDENTIAL``

A token credential used to authenticate HTTPS requests. The token value
should be updated before its expiration.
24 changes: 16 additions & 8 deletions storages/backends/azure_storage.py
Expand Up @@ -7,7 +7,7 @@

from azure.common import AzureMissingResourceHttpError
from azure.storage.blob import BlobPermissions, ContentSettings
from azure.storage.common import CloudStorageAccount
from azure.storage.blob.blockblobservice import BlockBlobService
from django.core.exceptions import SuspiciousOperation
from django.core.files.base import File
from django.core.files.storage import Storage
Expand Down Expand Up @@ -66,8 +66,6 @@ def read(self, *args, **kwargs):
return super(AzureStorageFile, self).read(*args, **kwargs)

def write(self, content):
if len(content) > 100*1024*1024:
raise ValueError("Max chunk size is 100MB")
if ('w' not in self._mode and
'+' not in self._mode and
'a' not in self._mode):
Expand Down Expand Up @@ -147,6 +145,11 @@ class AzureStorage(Storage):
location = setting('AZURE_LOCATION', '')
default_content_type = 'application/octet-stream'
is_emulated = setting('AZURE_EMULATED_MODE', False)
endpoint_suffix = setting('AZURE_ENDPOINT_SUFFIX')
sas_token = setting('AZURE_SAS_TOKEN')
custom_domain = setting('AZURE_CUSTOM_DOMAIN')
connection_string = setting('AZURE_CONNECTION_STRING')
token_credential = setting('AZURE_TOKEN_CREDENTIAL')

def __init__(self):
self._service = None
Expand All @@ -156,11 +159,16 @@ def service(self):
# This won't open a connection or anything,
# it's akin to a client
if self._service is None:
account = CloudStorageAccount(
self.account_name,
self.account_key,
is_emulated=self.is_emulated)
self._service = account.create_block_blob_service()
self._service = BlockBlobService(
account_name=self.account_name,
account_key=self.account_key,
sas_token=self.sas_token,
is_emulated=self.is_emulated,
protocol=self.azure_protocol,
custom_domain=self.custom_domain,
connection_string=self.connection_string,
token_credential=self.token_credential,
endpoint_suffix=self.endpoint_suffix)
return self._service

@property
Expand Down
6 changes: 6 additions & 0 deletions tests/integration/test_azure.py
Expand Up @@ -64,6 +64,12 @@ def test_url(self):
# has some query-string
self.assertTrue("/test/my_file.txt?" in self.storage.url("my_file.txt"))

def test_url_custom_endpoint(self):
storage = azure_storage.AzureStorage()
storage.is_emulated = True
storage.custom_domain = 'foobar:123456'
self.assertTrue(storage.url("my_file.txt").startswith('https://foobar:123456/'))

@override_settings(USE_TZ=True)
def test_get_modified_time_tz(self):
stream = io.BytesIO(b'Im a stream')
Expand Down
26 changes: 26 additions & 0 deletions tests/test_azure.py
Expand Up @@ -147,6 +147,32 @@ def test_url_expire(self):
sas_token='foo_token',
protocol='https')

def test_blob_service_params(self):
storage = azure_storage.AzureStorage()
storage.is_emulated = True
storage.endpoint_suffix = 'foo_suffix'
storage.account_name = 'foo_name'
storage.account_key = 'foo_key'
storage.sas_token = 'foo_token'
storage.azure_ssl = True
storage.custom_domain = 'foo_domain'
storage.connection_string = 'foo_conn'
storage.token_credential = 'foo_cred'
with mock.patch(
'storages.backends.azure_storage.BlockBlobService',
autospec=True) as c_mocked:
self.assertIsNotNone(storage.service)
c_mocked.assert_called_once_with(
account_name='foo_name',
account_key='foo_key',
sas_token='foo_token',
is_emulated=True,
protocol='https',
custom_domain='foo_domain',
connection_string='foo_conn',
token_credential='foo_cred',
endpoint_suffix='foo_suffix')

# From boto3

def test_storage_save(self):
Expand Down

0 comments on commit a6ea342

Please sign in to comment.