def download(self, storagemodel: object, modeldefinition=None): """ load blob from storage into StorageBlobModelInstance """ if (storagemodel.name is None): # No content to download raise AzureStorageWrapException( storagemodel, "StorageBlobModel does not contain content nor content settings" ) else: container_name = modeldefinition['container'] blob_name = storagemodel.name try: if modeldefinition['blobservice'].exists( container_name, blob_name): """ download blob """ blob = modeldefinition['blobservice'].get_blob_to_bytes( container_name=modeldefinition['container'], blob_name=storagemodel.name) storagemodel.__mergeblob__(blob) except Exception as e: msg = 'can not load blob from container {} because {!s}'.format( storagemodel._containername, e) raise AzureStorageWrapException(storagemodel, msg=msg) return storagemodel
def tofile(self, path_to_file, replace_file=False): """ save blob content from StorageBlobModel instance to file in given path/file. Parameters are: - path_to_file (required): local path or file """ # create full path if os.path.isdir(path_to_file): if self.filename != '': path_to_file = os.path.join(path_to_file, self.filename) else: # guess extention from mimetype path_to_file = os.path.join( path_to_file, self.name + guess_extension( self.properties.content_settings.content_type)) elif os.path.isfile(path_to_file): # check if given file extention fits to self.filename or mime type # if self.filename != '': if os.path.splitext( self.filename)[1] != os.path.splitext(path_to_file)[1]: raise AzureStorageWrapException( self, 'can not save blob to file because file extention {!s} does not fit to source file or mime type' .format(path_to_file)) else: mimetype = guess_type(path_to_file)[0] if mimtype != self.properties.content_settings.content_type: raise AzureStorageWrapException( self, 'can not save blob to file because file extention {!s} does not fit to source file or mime type' .format(path_to_file)) else: raise AzureStorageWrapException( self, 'can not save blob to file because {!s} is not a dir nor a file' .format(path_to_file)) # check if file exists (and replace or error) if os.path.isfile(path_to_file): if replace_file: os.remove(path_to_file) else: raise AzureStorageWrapException( self, 'can not save blob to file {!s} because file exists and replace_file is False' .format(path_to_file)) # save file into self.__content__ self.filename = os.path.basename(path_to_file) with open(path_to_file, "wb") as out_file: out_file.write(self.content) return path_to_file
def wrapper(self, storagemodel, modeldefinition=None, *args, **kwargs): """ modeldefinition already determined """ if not modeldefinition is None: return func(self, storagemodel, modeldefinition, *args, **kwargs) """ find modeldefinition for StorageQueueModel or StorageQueueModel """ if isinstance(storagemodel, StorageBlobModel): definitionlist = [ definition for definition in self._modeldefinitions if definition['modelname'] == storagemodel.__class__.__name__ ] else: log.info('Argument is not an StorageBlobModel') raise AzureStorageWrapException( storagemodel, "Argument is not an StorageBlobModel") if len(definitionlist) == 1: modeldefinition = definitionlist[0] elif len(definitionlist) > 1: raise ModelRegisteredMoreThanOnceError(storagemodel) if registered and (not isinstance(modeldefinition, dict)): raise ModelNotRegisteredError(storagemodel) return func(self, storagemodel, modeldefinition, *args, **kwargs)
def exists(self, storagemodel) -> bool: modeldefinition = self.getmodeldefinition(storagemodel, True) exists = False if storagemodel._exists is None: try: pk = storagemodel.getPartitionKey() rk = storagemodel.getRowKey() entity = modeldefinition['tableservice'].get_entity( modeldefinition['tablename'], pk, rk) storagemodel._exists = True exists = True except AzureMissingResourceHttpError: storagemodel._exists = False except Exception as e: msg = 'failed to test {} with error {}'.format( modeldefinition['tablename'], e) raise AzureStorageWrapException(msg=msg) else: exists = storagemodel._exists return exists
def get(self, storagemodel) -> StorageTableModel: """ load entity data from storage to vars in self """ modeldefinition = self.getmodeldefinition(storagemodel, True) try: pk = storagemodel.getPartitionKey() rk = storagemodel.getRowKey() entity = modeldefinition['tableservice'].get_entity( modeldefinition['tablename'], pk, rk) storagemodel._exists = True """ sync with entity values """ for key, default in vars(storagemodel).items(): if not key.startswith('_') and key not in [ '', 'PartitionKey', 'RowKey' ]: value = getattr(entity, key, None) if not value is None: setattr(storagemodel, key, value) except AzureMissingResourceHttpError as e: log.debug( 'can not get table entity: Table {}, PartitionKey {}, RowKey {} because {!s}' .format(modeldefinition['tablename'], pk, rk, e)) storagemodel._exists = False except Exception as e: msg = 'can not get table entity: Table {}, PartitionKey {}, RowKey {} because {!s}'.format( modeldefinition['tablename'], pk, rk, e) raise AzureStorageWrapException(msg=msg) finally: return storagemodel
def fromfile(self, path_to_file, mimetype=None): """ load blob content from file in StorageBlobModel instance. Parameters are: - path_to_file (required): path to a local file - mimetype (optional): set a mimetype. azurestoragewrap will guess it if not given """ if os.path.isfile(path_to_file): # Load file into self.__content__ self.filename = os.path.basename(path_to_file) with open(path_to_file, "rb") as in_file: self.content = in_file.read() #guess mime-type self.properties.content_settings = ContentSettings() if mimetype is None: mimetype = guess_type(path_to_file) if mimetype[0] is None: mimetype = 'application/octet-stream' else: if not mimetype[1] is None: self.properties.content_settings.content_encoding = mimetype[ 1] mimetype = mimetype[0] self.properties.content_settings.content_type = mimetype else: raise AzureStorageWrapException( self, 'Can not load blob content, because given path is not a local file' )
def insert(self, storagemodel) -> StorageTableModel: """ insert model into storage """ modeldefinition = self.getmodeldefinition(storagemodel, True) try: modeldefinition['tableservice'].insert_or_replace_entity( modeldefinition['tablename'], storagemodel.entity()) storagemodel._exists = True except AzureMissingResourceHttpError as e: storagemodel._exists = False log.debug( 'can not insert or replace table entity: Table {}, PartitionKey {}, RowKey {} because {!s}' .format(modeldefinition['tablename'], storagemodel.getPartitionKey(), storagemodel.getRowKey(), e)) except Exception as e: storagemodel._exists = False msg = 'can not insert or replace table entity: Table {}, PartitionKey {}, RowKey {} because {!s}'.format( modeldefinition['tablename'], storagemodel.PartitionKey, storagemodel.RowKey, e) raise AzureStorageWrapException(msg=msg) finally: return storagemodel
def query(self, storagequery) -> StorageTableQuery: modeldefinition = self.getmodeldefinition(storagequery, True) try: if (not storagequery._select is None) and (storagequery._select != ''): storagequery.extend( modeldefinition['tableservice'].query_entities( modeldefinition['tablename'], filter=storagequery._queryfilter, select=storagequery._select)) else: storagequery.extend( modeldefinition['tableservice'].query_entities( modeldefinition['tablename'], filter=storagequery._queryfilter)) except AzureMissingResourceHttpError as e: storagequery = [] log.debug( 'can not query table {} with filters {} because {!s}'.format( modeldefinition['tablename'], storagequery._queryfilter, e)) except Exception as e: msg = 'can not query table {} with filters {} because {!s}'.format( modeldefinition['tablename'], storagequery._queryfilter, e) raise AzureStorageWrapException(msg=msg) return storagequery
def table_isempty(self, tablename, PartitionKey='', RowKey='') -> bool: if (not self._tableservice is None): filter = "PartitionKey eq '{}'".format( PartitionKey) if PartitionKey != '' else '' if filter == '': filter = "RowKey eq '{}'".format( RowKey) if RowKey != '' else '' else: filter = filter + ("and RowKey eq '{}'".format(RowKey) if RowKey != '' else '') try: entities = list(modeldefinition['tableservice'].query_entities( tablename, filter=filter, select='PartitionKey', num_results=1)) if len(entities) == 1: return False else: return True except AzureMissingResourceHttpError as e: log.debug('failed to query {} with error {}'.format( tablename, e)) return True except Exception as e: msg = '{!s}'.format(e) raise AzureStorageWrapException(msg=msg) else: return True pass
def update(self, storagemodel:object, modeldefinition = None, hide = 0) -> StorageQueueModel: """ update the message in queue """ if (storagemodel.id != '') and (storagemodel.pop_receipt != '') and (not storagemodel.id is None) and (not storagemodel.pop_receipt is None): try: content = storagemodel.getmessage() message = modeldefinition['queueservice'].update_message(storagemodel._queuename, storagemodel.id, storagemodel.pop_receipt, visibility_timeout = hide, content=content) storagemodel.content = content storagemodel.pop_receipt = message.pop_receipt except Exception as e: msg = 'can not update queue message: queue {} with message.id {!s} because {!s}'.format(storagemodel._queuename, storagemodel.id, e) storagemodel = None raise AzureStorageWrapException(msg=msg) else: msg = 'cant update queuemessage in {!s} due to missing id {!s} and/or pop_receipt {!s}'.format(storagemodel._queuename, storagemodel.id, storagemodel.pop_receipt) storagemodel = None raise AzureStorageWrapException(msg=msg) return storagemodel
def put(self, storagemodel:object, modeldefinition = None) -> StorageQueueModel: """ insert queue message into storage """ try: message = modeldefinition['queueservice'].put_message(storagemodel._queuename, storagemodel.getmessage()) storagemodel.mergemessage(message) except Exception as e: storagemodel = None msg = 'can not save queue message: queue {} with message {} because {!s}'.format(storagemodel._queuename, storagemodel.content, e) raise AzureStorageWrapException(msg=msg) finally: return storagemodel
def __deletequeue__(self, modeldefinition:dict) -> bool: if (not modeldefinition['queueservice'] is None): try: modeldefinition['queueservice'].delete_queue(modeldefinition['queuename']) return True except Exception as e: msg = 'failed to delete {} with error {}'.format(modeldefinition['queuename'], e) raise AzureStorageWrapException(msg=msg) else: return True pass
def __deletetable__(self, modeldefinition: dict) -> bool: if (not modeldefinition['tableservice'] is None): try: modeldefinition['tableservice'].delete_table( modeldefinition['tablename']) return True except Exception as e: msg = 'failed to create {} with error {}'.format(tablename, e) raise AzureStorageWrapException(msg=msg) else: return False pass
def upload(self, storagemodel: object, modeldefinition=None): """ insert blob message into storage """ if (storagemodel.content is None) or ( storagemodel.properties.content_settings.content_type is None): # No content to upload raise AzureStorageWrapException( storagemodel, "StorageBlobModel does not contain content nor content settings" ) else: blobservice = modeldefinition['blobservice'] container_name = modeldefinition['container'] blob_name = storagemodel.name try: # refresh metadata storagemodel.__instance_to_metadata__() """ upload bytes """ blobservice.create_blob_from_bytes( container_name=container_name, blob_name=blob_name, blob=storagemodel.content, metadata=storagemodel.metadata, content_settings=storagemodel.properties.content_settings) storagemodel.properties = blobservice.get_blob_properties( container_name=container_name, blob_name=blob_name).properties except Exception as e: msg = 'can not save blob in container {} because {!s}'.format( storagemodel._containername, e) raise AzureStorageWrapException(storagemodel, msg=msg) return storagemodel
def __create__(self, modeldefinition: dict) -> bool: if (not modeldefinition['blobservice'] is None): try: modeldefinition['blobservice'].create_container( modeldefinition['container']) return True except Exception as e: msg = 'failed to create {} with error {}'.format( modeldefinition['container'], e) raise AzureStorageWrapException(msg=msg) else: return True pass
def totext(self) -> str: """ return blob content from StorageBlobModel instance to a string. Parameters are: """ sreturn = '' if self.properties.content_settings.content_encoding is None: raise AzureStorageWrapException( self, 'can not convert blob {!s} to text because content_encoding is not given' .format(self.name)) else: sreturn = self.content.decode( self.properties.content_settings.content_encoding, 'ignore') return sreturn
def delete(self, storagemodel:object, modeldefinition = None) -> bool: """ delete the message in queue """ deleted = False if (storagemodel.id != '') and (storagemodel.pop_receipt != '') and (not storagemodel.id is None) and (not storagemodel.pop_receipt is None): try: modeldefinition['queueservice'].delete_message(storagemodel._queuename, storagemodel.id, storagemodel.pop_receipt) deleted = True except Exception as e: msg = 'can not delete queue message: queue {} with message.id {!s} because {!s}'.format(storagemodel._queuename, storagemodel.id, e) raise AzureStorageWrapException(msg=msg) else: log.info('cant update queuemessage {} due to missing id and pop_receipt'.format(storagemodel._queuename)) return deleted
def delete(self, storagemodel: object, modeldefinition=None) -> bool: """ delete the blob from storage """ deleted = False blobservice = modeldefinition['blobservice'] container_name = modeldefinition['container'] blob_name = storagemodel.name try: if blobservice.exists(container_name, blob_name): """ delete """ blob = blobservice.delete_blob(container_name, blob_name) deleted = True except Exception as e: msg = 'can not delete blob {} from storage because {!s}'.format( blob_name, e) raise AzureStorageWrapException(storagemodel, msg=msg) return deleted
def peek(self, storagemodel:object, modeldefinition = None) -> StorageQueueModel: """ lookup the next message in queue """ try: messages = modeldefinition['queueservice'].peek_messages(storagemodel._queuename, num_messages=1) """ parse retrieved message """ for message in messages: storagemodel.mergemessage(message) """ no message retrieved ?""" if storagemodel.id is None: storagemodel = None except Exception as e: storagemodel = None msg = 'can not peek queue message: queue {} with message {} because {!s}'.format(storagemodel._queuename, storagemodel.content, e) raise AzureStorageWrapException(msg=msg) finally: return storagemodel
def fromtext(self, text, encoding='utf-8', mimetype='text/plain'): """ set blob content from given text in StorageBlobModel instance. Parameters are: - text (required): path to a local file - encoding (optional): text encoding (default is utf-8) - mimetype (optional): set a mimetype. azurestoragewrap will guess it if not given """ if isinstance(text, str): text = text.encode(encoding, 'ignore') # Load text into self.__content__ self.content = bytes(text) self.properties.content_settings = ContentSettings( content_type=mimetype, content_encoding=encoding) else: raise AzureStorageWrapException( self, 'Can not load blob content, because given text is not from type string' )
def exists(self, storagemodel: object, modeldefinition=None) -> bool: """ delete the blob from storage """ exists = False blobservice = modeldefinition['blobservice'] container_name = modeldefinition['container'] blob_name = storagemodel.name try: blobs = self.list(storagemodel, modeldefinition, where=storagemodel.name) if len(blobs) == 1: storagemodel.__mergeblob__(blobs[0]) exists = True except Exception as e: msg = 'can not retireve blob {} from storage because {!s}'.format( blob_name, e) raise AzureStorageWrapException(storagemodel, msg=msg) return exists
def get(self, storagemodel:object, modeldefinition = None, hide = 0) -> StorageQueueModel: """ get the next message in queue """ try: if hide > 0: messages = modeldefinition['queueservice'].get_messages(storagemodel._queuename, num_messages=1, visibility_timeout = hide) else: messages = modeldefinition['queueservice'].get_messages(storagemodel._queuename, num_messages=1) """ parse retrieved message """ for message in messages: storagemodel.mergemessage(message) """ no message retrieved ?""" if storagemodel.id is None: storagemodel = None except Exception as e: storagemodel = None msg = 'can not peek queue message: queue {} with message {} because {!s}'.format(storagemodel._queuename, storagemodel.content, e) raise AzureStorageWrapException(msg=msg) finally: return storagemodel
def list(self, storagemodel: object, modeldefinition=None, where=None) -> list: """ list blob messages in container """ try: blobnames = [] if where is None: generator = modeldefinition['blobservice'].list_blobs( modeldefinition['container']) else: generator = modeldefinition['blobservice'].list_blobs( modeldefinition['container'], prefix=where) for blob in generator: blobnames.append(blob) except Exception as e: msg = 'can not list blobs in container {} because {!s}'.format( storagemodel._containername, e) raise AzureStorageWrapException(storagemodel, msg=msg) finally: return blobnames