-
-
Notifications
You must be signed in to change notification settings - Fork 329
Fixed '/' prepend bug in ABSStore #526
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
Changes from all commits
50913cb
7f5c5a9
b18607d
42274a8
711c9f3
c24407c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1964,7 +1964,7 @@ class ABSStore(MutableMapping): | |
In order to use this store, you must install the Microsoft Azure Storage SDK for Python. | ||
""" | ||
|
||
def __init__(self, container, prefix, account_name=None, account_key=None, | ||
def __init__(self, container, prefix='', account_name=None, account_key=None, | ||
blob_service_kwargs=None): | ||
from azure.storage.blob import BlockBlobService | ||
self.container = container | ||
|
@@ -1990,21 +1990,25 @@ def __setstate__(self, state): | |
self.client = BlockBlobService(self.account_name, self.account_key, | ||
**self.blob_service_kwargs) | ||
|
||
@staticmethod | ||
def _append_path_to_prefix(path, prefix): | ||
return '/'.join([normalize_storage_path(prefix), | ||
normalize_storage_path(path)]) | ||
def _append_path_to_prefix(self, path): | ||
if self.prefix == '': | ||
return normalize_storage_path(path) | ||
else: | ||
return '/'.join([self.prefix, normalize_storage_path(path)]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So what happens here if prefix='/'? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay great. Thanks. |
||
|
||
@staticmethod | ||
def _strip_prefix_from_path(path, prefix): | ||
# normalized things will not have any leading or trailing slashes | ||
path_norm = normalize_storage_path(path) | ||
prefix_norm = normalize_storage_path(prefix) | ||
return path_norm[(len(prefix_norm)+1):] | ||
if prefix: | ||
return path_norm[(len(prefix_norm)+1):] | ||
else: | ||
return path_norm | ||
|
||
def __getitem__(self, key): | ||
from azure.common import AzureMissingResourceHttpError | ||
blob_name = '/'.join([self.prefix, key]) | ||
blob_name = self._append_path_to_prefix(key) | ||
try: | ||
blob = self.client.get_blob_to_bytes(self.container, blob_name) | ||
return blob.content | ||
|
@@ -2013,13 +2017,13 @@ def __getitem__(self, key): | |
|
||
def __setitem__(self, key, value): | ||
value = ensure_bytes(value) | ||
blob_name = '/'.join([self.prefix, key]) | ||
blob_name = self._append_path_to_prefix(key) | ||
self.client.create_blob_from_bytes(self.container, blob_name, value) | ||
|
||
def __delitem__(self, key): | ||
from azure.common import AzureMissingResourceHttpError | ||
try: | ||
self.client.delete_blob(self.container, '/'.join([self.prefix, key])) | ||
self.client.delete_blob(self.container, self._append_path_to_prefix(key)) | ||
except AzureMissingResourceHttpError: | ||
raise KeyError('Blob %s not found' % key) | ||
|
||
|
@@ -2034,53 +2038,62 @@ def keys(self): | |
return list(self.__iter__()) | ||
|
||
def __iter__(self): | ||
for blob in self.client.list_blobs(self.container, self.prefix + '/'): | ||
if self.prefix: | ||
list_blobs_prefix = self.prefix + '/' | ||
else: | ||
list_blobs_prefix = None | ||
for blob in self.client.list_blobs(self.container, list_blobs_prefix): | ||
yield self._strip_prefix_from_path(blob.name, self.prefix) | ||
|
||
def __len__(self): | ||
return len(self.keys()) | ||
|
||
def __contains__(self, key): | ||
blob_name = '/'.join([self.prefix, key]) | ||
blob_name = self._append_path_to_prefix(key) | ||
if self.client.exists(self.container, blob_name): | ||
return True | ||
else: | ||
return False | ||
|
||
def listdir(self, path=None): | ||
store_path = normalize_storage_path(path) | ||
# prefix is normalized to not have a trailing slash | ||
dir_path = self.prefix | ||
if store_path: | ||
dir_path = dir_path + '/' + store_path | ||
dir_path += '/' | ||
from azure.storage.blob import Blob | ||
dir_path = normalize_storage_path(self._append_path_to_prefix(path)) | ||
if dir_path: | ||
dir_path += '/' | ||
items = list() | ||
for blob in self.client.list_blobs(self.container, prefix=dir_path, delimiter='/'): | ||
if '/' in blob.name[len(dir_path):]: | ||
if type(blob) == Blob: | ||
items.append(self._strip_prefix_from_path(blob.name, dir_path)) | ||
else: | ||
items.append(self._strip_prefix_from_path( | ||
blob.name[:blob.name.find('/', len(dir_path))], dir_path)) | ||
else: | ||
items.append(self._strip_prefix_from_path(blob.name, dir_path)) | ||
return items | ||
|
||
def rmdir(self, path=None): | ||
dir_path = normalize_storage_path(self._append_path_to_prefix(path, self.prefix)) + '/' | ||
dir_path = normalize_storage_path(self._append_path_to_prefix(path)) | ||
if dir_path: | ||
dir_path += '/' | ||
for blob in self.client.list_blobs(self.container, prefix=dir_path): | ||
self.client.delete_blob(self.container, blob.name) | ||
|
||
def getsize(self, path=None): | ||
from azure.storage.blob import Blob | ||
store_path = normalize_storage_path(path) | ||
fs_path = self.prefix | ||
if store_path: | ||
fs_path = self._append_path_to_prefix(store_path, self.prefix) | ||
fs_path = self._append_path_to_prefix(store_path) | ||
if self.client.exists(self.container, fs_path): | ||
return self.client.get_blob_properties(self.container, | ||
fs_path).properties.content_length | ||
else: | ||
size = 0 | ||
for blob in self.client.list_blobs(self.container, prefix=fs_path + '/', | ||
if fs_path == '': | ||
fs_path = None | ||
else: | ||
fs_path += '/' | ||
for blob in self.client.list_blobs(self.container, prefix=fs_path, | ||
delimiter='/'): | ||
if '/' not in blob.name[len(fs_path + '/'):]: | ||
if type(blob) == Blob: | ||
size += blob.properties.content_length | ||
return size | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering, what happens here if
self.prefix
isNone
(default)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During instantiation in the
__init__
function, anyprefix
supplied is passed to thezarr.util.normalize_storage_path
function before storing it inself.prefix
, so if prefix isNone
it will be stored as''
inself.prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah cool, thanks. In which case maybe the default value for the prefix parameter could the empty string rather than None, might be a little more obvious. Also if prefix is normalised in the constructor then probably could remove calls to normalize self.prefix in the methods.