Module libnova.common.filesystem.S3.File
Expand source code
#!/usr/bin/env python
# coding: utf-8
import botocore
import urllib.parse
from libnova.common.filesystem import S3
from libnova.common.filesystem.S3 import FileStream
def get_stream(storage, file):
"""Retrieve a stream from an S3 Object given a platform `Storage` and `File`
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
file (libnova.common.api.File): A platform `File` object
Returns:
io.RawIOBase: An S3 object stream
"""
bucket = storage.extra_data["bucket"]
file_path = file.container_id + file.fullpath
return get_file_stream(bucket, file_path)
def get_container_file_stream(storage, container_id, object_key):
"""Retrieve a stream from an S3 Object given a platform `Storage` and `File`
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container_id (int): A platform `Container` id
object_key (str): The target S3 object key
Returns:
io.RawIOBase: An S3 object stream
"""
bucket = storage.extra_data["bucket"]
return get_file_stream(bucket, str(container_id) + object_key)
def get_bytes(storage, file):
"""Retrieve an array of bytes from an S3 Object given a platform `Storage` and `File`
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
file (libnova.common.api.File): A platform `File` object
Returns:
bytearray: The byte array of data from the file
"""
file_stream = S3.File.get_stream(
# The storage is needed to set the source bucket of the file
storage,
file
)
file_content = b''
if file_stream is not None:
file_stream_buffer = file_stream.read(8 * 1024 * 1024)
while file_stream_buffer:
file_content = b''.join([file_content, file_stream_buffer])
file_stream_buffer = file_stream.read(8 * 1024 * 1024)
return file_content
def get_container_file_bytes(storage, container_id, object_key):
"""Retrieve an array of bytes from an S3 Object using a given platform `Container` and the `object_key`
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container_id (int): A platform `Container` id
object_key (str): The S3 object key
Returns:
bytearray: The byte array of data from the file
"""
file_stream = S3.File.get_container_file_stream(
# The storage is needed to set the source bucket of the file
storage,
container_id,
object_key
)
file_content = b''
if file_stream is not None:
file_stream_buffer = file_stream.read(8 * 1024 * 1024)
while file_stream_buffer:
file_content = b''.join([file_content, file_stream_buffer])
file_stream_buffer = file_stream.read(8 * 1024 * 1024)
return file_content
def get_file_stream(bucket, file_path):
"""Retrieve a stream from an S3 Object given a bucket and a file path
Args:
bucket (str): An S3 bucket
file_path (str): A file path inside the bucket
Returns:
io.RawIOBase: An S3 object stream
"""
#client = S3.Storage.get_resource()
#
#s3object = client.Object(bucket_name=bucket, key=file_path)
#if s3object is not None:
# return FileStream.FileStream(s3object)
client = S3.Storage.get_client()
s3object = client.get_object(Bucket=bucket, Key=file_path)
if s3object is not None:
return s3object['Body']._raw_stream
print("Can't get stream from remote file /" + str(bucket) + "/" + file_path)
return None
def upload_storage_container_file(storage, container, object_key, local_file_path):
"""Upload a file to S3 using a given platform `Storage` and `Container` object to a target `object_key`,
using `local_file_path` as the source file to upload
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container (libnova.common.api.Container): A platform `Container` object
object_key (str): The target S3 object key
local_file_path (str): The local file to use as the file source to upload to S3
"""
upload_file(storage.extra_data["bucket"], container.id, object_key, local_file_path)
def upload_storage_container_stream(storage, container, object_key, stream):
"""Upload a file to S3 using a given platform `Storage` and `Container` object to a target `object_key`,
using `stream` as the data source to upload
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container (libnova.common.api.Container): A platform `Container` object
object_key (str): The target S3 object key
stream (io.RawIOBase): The stream to use as data source
"""
upload_stream(storage.extra_data["bucket"], container.id, object_key, stream)
def upload_file(bucket, container_id, object_key, local_file_path):
"""Upload a file to an S3 `bucket` using a given platform `Container` id to a target `object_key`,
using `local_file_path` as the source file to upload
Args:
bucket (str): The target S3 bucket
container_id (int): A platform `Container` id
object_key (str): The target S3 object key
local_file_path (str): The local file to use as the file source to upload to S3
"""
upload_stream(bucket, container_id, object_key, open(local_file_path, 'rb'))
def upload_stream(bucket, container_id, object_key, stream):
"""Upload a file to an S3 `bucket` using a given platform `Container` id to a target `object_key`,
using `stream` as the data source to upload
Args:
bucket (str): The target S3 bucket
container_id (int): A platform `Container` id
object_key (str): The target S3 object key
stream (io.RawIOBase): The stream to use as data source
"""
__upload_stream(bucket, str(container_id) + '/' + object_key.lstrip("/"), stream)
def __upload_stream(bucket, object_key, stream):
"""Upload a file to an S3 `bucket` and `object_key`,
using `stream` as the data source to upload
Args:
bucket (str): The target S3 bucket
object_key (str): The target S3 object key
stream (io.RawIOBase): The stream to use as data source
"""
client = S3.Storage.get_resource()
client.Object(bucket, object_key.lstrip("/")).put(Body=stream)
def get_directory_contents(bucket, container_id, object_key):
client = S3.Storage.get_resource()
bucket = client.Bucket(bucket)
prefix = str(container_id) + '/' + object_key.strip('/') + '/'
result = bucket.meta.client.list_objects(Bucket=bucket.name, Prefix=prefix, Delimiter='/')
prefixes = [remote_prefix[len(str(container_id)):] for remote_prefix in list(map(lambda item: item.get('Prefix'), result.get('CommonPrefixes', []))) if remote_prefix != prefix]
contents = [remote_content[len(str(container_id)):] for remote_content in list(map(lambda item: item.get('Key'), result.get('Contents', []))) if not remote_content.endswith('/')]
return prefixes + contents
def create_directory(bucket, container_id, object_key):
client = S3.Storage.get_client()
client.put_object(Bucket=bucket, Key=str(container_id) + '/' + object_key.strip('/') + '/')
def directory_exists(bucket, container_id, object_key):
client = S3.Storage.get_client()
result = client.list_objects(Bucket=bucket, Prefix=str(container_id) + '/' + object_key.lstrip('/'))
if 'Contents' in result:
return True
return False
def move(bucket, source_object_key, target_object_key, preserve_meta = True):
client = S3.Storage.get_resource()
try:
copy_source = {
'Bucket': bucket,
'Key': source_object_key
}
extra = {}
if preserve_meta:
extra = {'Metadata': get_file_metadata(bucket, source_object_key)}
client.meta.client.copy(copy_source, bucket, target_object_key, ExtraArgs=extra)
except Exception as e:
return False
finally:
client.Object(bucket_name=bucket, key=source_object_key).delete()
return True
def head(bucket, object_key):
try:
return S3.Storage.get_client().head_object(Bucket=bucket, Key=object_key)
except:
pass
return None
def get_container_file_metadata(storage, container_id, object_key, custom_fields_only = True):
"""Get the metadata of a given S3 object key and a platform `Container` id
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container_id (int): A platform `Container` id
object_key (str): The S3 object key
custom_fields_only (bool): Skip the fields set by S3 and return only our own metadata
"""
return get_file_metadata(storage.extra_data["bucket"], str(container_id) + '/' + object_key.lstrip('/'), custom_fields_only)
def get_file_metadata(bucket, object_key, custom_fields_only=True):
"""Get the metadata of a given S3 object key
Args:
bucket (str): An S3 bucket
object_key (str): The S3 object key
custom_fields_only (bool): Skip the fields set by S3 and return only our own metadata
"""
resource = S3.Storage.get_resource()
meta = {}
s3head = head(bucket, object_key)
if s3head is not None:
if 'ResponseMetadata' in s3head:
if 'HTTPHeaders' in s3head['ResponseMetadata']:
if custom_fields_only:
for header_key in s3head['ResponseMetadata']['HTTPHeaders'].keys():
if header_key.startswith('x-amz-meta-'):
meta[header_key[len('x-amz-meta-'):]] = s3head['ResponseMetadata']['HTTPHeaders'][header_key]
else:
meta = s3head['ResponseMetadata']['HTTPHeaders']
return meta
def container_file_head(bucket, container_id, object_key):
return head(bucket, str(container_id) + '/' + object_key.lstrip('/'))
def exists(bucket, container_id, object_key):
client = S3.Storage.get_client()
try:
head = client.head_object(Bucket=bucket, Key=str(container_id) + '/' + object_key.lstrip('/'))
return True
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
return False
raise
def presign(bucket, object_key, expiration=3600, range=[]):
client = S3.Storage.get_client()
try:
request_params = {
'Bucket': bucket,
'Key': object_key
}
if len(range) == 2:
request_params['Range'] = 'bytes=[{}-{}]'.format(range[0], range[1])
return client.generate_presigned_url(
'get_object',
Params= {
'Bucket': bucket,
'Key': object_key
},
ExpiresIn=expiration
)
except:
pass
return ""
def presign_container_file(bucket, container_id, object_key, expiration=3600, range=[]):
return presign(bucket, str(container_id)+"/"+object_key.lstrip('/'), expiration, range)
def get_versions(storage, container, object_key=""):
"""Get the versions of a given S3 object key
Args:
storage (libnova.common.api.Storage): A platform `Storage` object
container (libnova.common.api.Container): A platform `Container` object
object_key (str): The S3 object key
"""
resource = S3.Storage.get_resource()
bucket = storage.extra_data["bucket"]
return resource.Bucket(bucket).object_versions.filter(Prefix=str(container.id)+"/"+object_key.lstrip('/'))
if __name__ == "__main__":
print('This file cannot be executed directly!')
Functions
def container_file_head(bucket, container_id, object_key)
-
Expand source code
def container_file_head(bucket, container_id, object_key): return head(bucket, str(container_id) + '/' + object_key.lstrip('/'))
def create_directory(bucket, container_id, object_key)
-
Expand source code
def create_directory(bucket, container_id, object_key): client = S3.Storage.get_client() client.put_object(Bucket=bucket, Key=str(container_id) + '/' + object_key.strip('/') + '/')
def directory_exists(bucket, container_id, object_key)
-
Expand source code
def directory_exists(bucket, container_id, object_key): client = S3.Storage.get_client() result = client.list_objects(Bucket=bucket, Prefix=str(container_id) + '/' + object_key.lstrip('/')) if 'Contents' in result: return True return False
def exists(bucket, container_id, object_key)
-
Expand source code
def exists(bucket, container_id, object_key): client = S3.Storage.get_client() try: head = client.head_object(Bucket=bucket, Key=str(container_id) + '/' + object_key.lstrip('/')) return True except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == "404": return False raise
def get_bytes(storage, file)
-
Retrieve an array of bytes from an S3 Object given a platform
Storage
andFile
Args
storage
:libnova.common.api.Storage
- A platform
Storage
object file
:libnova.common.api.File
- A platform
File
object
Returns
bytearray
- The byte array of data from the file
Expand source code
def get_bytes(storage, file): """Retrieve an array of bytes from an S3 Object given a platform `Storage` and `File` Args: storage (libnova.common.api.Storage): A platform `Storage` object file (libnova.common.api.File): A platform `File` object Returns: bytearray: The byte array of data from the file """ file_stream = S3.File.get_stream( # The storage is needed to set the source bucket of the file storage, file ) file_content = b'' if file_stream is not None: file_stream_buffer = file_stream.read(8 * 1024 * 1024) while file_stream_buffer: file_content = b''.join([file_content, file_stream_buffer]) file_stream_buffer = file_stream.read(8 * 1024 * 1024) return file_content
def get_container_file_bytes(storage, container_id, object_key)
-
Retrieve an array of bytes from an S3 Object using a given platform
Container
and theobject_key
Args
storage
:libnova.common.api.Storage
- A platform
Storage
object container_id
:int
- A platform
Container
id object_key
:str
- The S3 object key
Returns
bytearray
- The byte array of data from the file
Expand source code
def get_container_file_bytes(storage, container_id, object_key): """Retrieve an array of bytes from an S3 Object using a given platform `Container` and the `object_key` Args: storage (libnova.common.api.Storage): A platform `Storage` object container_id (int): A platform `Container` id object_key (str): The S3 object key Returns: bytearray: The byte array of data from the file """ file_stream = S3.File.get_container_file_stream( # The storage is needed to set the source bucket of the file storage, container_id, object_key ) file_content = b'' if file_stream is not None: file_stream_buffer = file_stream.read(8 * 1024 * 1024) while file_stream_buffer: file_content = b''.join([file_content, file_stream_buffer]) file_stream_buffer = file_stream.read(8 * 1024 * 1024) return file_content
def get_container_file_metadata(storage, container_id, object_key, custom_fields_only=True)
-
Get the metadata of a given S3 object key and a platform
Container
idArgs
storage
:libnova.common.api.Storage
- A platform
Storage
object container_id
:int
- A platform
Container
id object_key
:str
- The S3 object key
custom_fields_only
:bool
- Skip the fields set by S3 and return only our own metadata
Expand source code
def get_container_file_metadata(storage, container_id, object_key, custom_fields_only = True): """Get the metadata of a given S3 object key and a platform `Container` id Args: storage (libnova.common.api.Storage): A platform `Storage` object container_id (int): A platform `Container` id object_key (str): The S3 object key custom_fields_only (bool): Skip the fields set by S3 and return only our own metadata """ return get_file_metadata(storage.extra_data["bucket"], str(container_id) + '/' + object_key.lstrip('/'), custom_fields_only)
def get_container_file_stream(storage, container_id, object_key)
-
Retrieve a stream from an S3 Object given a platform
Storage
andFile
Args
storage
:libnova.common.api.Storage
- A platform
Storage
object container_id
:int
- A platform
Container
id object_key
:str
- The target S3 object key
Returns
io.RawIOBase
- An S3 object stream
Expand source code
def get_container_file_stream(storage, container_id, object_key): """Retrieve a stream from an S3 Object given a platform `Storage` and `File` Args: storage (libnova.common.api.Storage): A platform `Storage` object container_id (int): A platform `Container` id object_key (str): The target S3 object key Returns: io.RawIOBase: An S3 object stream """ bucket = storage.extra_data["bucket"] return get_file_stream(bucket, str(container_id) + object_key)
def get_directory_contents(bucket, container_id, object_key)
-
Expand source code
def get_directory_contents(bucket, container_id, object_key): client = S3.Storage.get_resource() bucket = client.Bucket(bucket) prefix = str(container_id) + '/' + object_key.strip('/') + '/' result = bucket.meta.client.list_objects(Bucket=bucket.name, Prefix=prefix, Delimiter='/') prefixes = [remote_prefix[len(str(container_id)):] for remote_prefix in list(map(lambda item: item.get('Prefix'), result.get('CommonPrefixes', []))) if remote_prefix != prefix] contents = [remote_content[len(str(container_id)):] for remote_content in list(map(lambda item: item.get('Key'), result.get('Contents', []))) if not remote_content.endswith('/')] return prefixes + contents
def get_file_metadata(bucket, object_key, custom_fields_only=True)
-
Get the metadata of a given S3 object key
Args
bucket
:str
- An S3 bucket
object_key
:str
- The S3 object key
custom_fields_only
:bool
- Skip the fields set by S3 and return only our own metadata
Expand source code
def get_file_metadata(bucket, object_key, custom_fields_only=True): """Get the metadata of a given S3 object key Args: bucket (str): An S3 bucket object_key (str): The S3 object key custom_fields_only (bool): Skip the fields set by S3 and return only our own metadata """ resource = S3.Storage.get_resource() meta = {} s3head = head(bucket, object_key) if s3head is not None: if 'ResponseMetadata' in s3head: if 'HTTPHeaders' in s3head['ResponseMetadata']: if custom_fields_only: for header_key in s3head['ResponseMetadata']['HTTPHeaders'].keys(): if header_key.startswith('x-amz-meta-'): meta[header_key[len('x-amz-meta-'):]] = s3head['ResponseMetadata']['HTTPHeaders'][header_key] else: meta = s3head['ResponseMetadata']['HTTPHeaders'] return meta
def get_file_stream(bucket, file_path)
-
Retrieve a stream from an S3 Object given a bucket and a file path
Args
bucket
:str
- An S3 bucket
file_path
:str
- A file path inside the bucket
Returns
io.RawIOBase
- An S3 object stream
Expand source code
def get_file_stream(bucket, file_path): """Retrieve a stream from an S3 Object given a bucket and a file path Args: bucket (str): An S3 bucket file_path (str): A file path inside the bucket Returns: io.RawIOBase: An S3 object stream """ #client = S3.Storage.get_resource() # #s3object = client.Object(bucket_name=bucket, key=file_path) #if s3object is not None: # return FileStream.FileStream(s3object) client = S3.Storage.get_client() s3object = client.get_object(Bucket=bucket, Key=file_path) if s3object is not None: return s3object['Body']._raw_stream print("Can't get stream from remote file /" + str(bucket) + "/" + file_path) return None
def get_stream(storage, file)
-
Retrieve a stream from an S3 Object given a platform
Storage
andFile
Args
storage
:libnova.common.api.Storage
- A platform
Storage
object file
:libnova.common.api.File
- A platform
File
object
Returns
io.RawIOBase
- An S3 object stream
Expand source code
def get_stream(storage, file): """Retrieve a stream from an S3 Object given a platform `Storage` and `File` Args: storage (libnova.common.api.Storage): A platform `Storage` object file (libnova.common.api.File): A platform `File` object Returns: io.RawIOBase: An S3 object stream """ bucket = storage.extra_data["bucket"] file_path = file.container_id + file.fullpath return get_file_stream(bucket, file_path)
def get_versions(storage, container, object_key='')
-
Get the versions of a given S3 object key
Args
storage
:libnova.common.api.Storage
- A platform
Storage
object container
:libnova.common.api.Container
- A platform
Container
object object_key
:str
- The S3 object key
Expand source code
def get_versions(storage, container, object_key=""): """Get the versions of a given S3 object key Args: storage (libnova.common.api.Storage): A platform `Storage` object container (libnova.common.api.Container): A platform `Container` object object_key (str): The S3 object key """ resource = S3.Storage.get_resource() bucket = storage.extra_data["bucket"] return resource.Bucket(bucket).object_versions.filter(Prefix=str(container.id)+"/"+object_key.lstrip('/'))
def head(bucket, object_key)
-
Expand source code
def head(bucket, object_key): try: return S3.Storage.get_client().head_object(Bucket=bucket, Key=object_key) except: pass return None
def move(bucket, source_object_key, target_object_key, preserve_meta=True)
-
Expand source code
def move(bucket, source_object_key, target_object_key, preserve_meta = True): client = S3.Storage.get_resource() try: copy_source = { 'Bucket': bucket, 'Key': source_object_key } extra = {} if preserve_meta: extra = {'Metadata': get_file_metadata(bucket, source_object_key)} client.meta.client.copy(copy_source, bucket, target_object_key, ExtraArgs=extra) except Exception as e: return False finally: client.Object(bucket_name=bucket, key=source_object_key).delete() return True
def presign(bucket, object_key, expiration=3600, range=[])
-
Expand source code
def presign(bucket, object_key, expiration=3600, range=[]): client = S3.Storage.get_client() try: request_params = { 'Bucket': bucket, 'Key': object_key } if len(range) == 2: request_params['Range'] = 'bytes=[{}-{}]'.format(range[0], range[1]) return client.generate_presigned_url( 'get_object', Params= { 'Bucket': bucket, 'Key': object_key }, ExpiresIn=expiration ) except: pass return ""
def presign_container_file(bucket, container_id, object_key, expiration=3600, range=[])
-
Expand source code
def presign_container_file(bucket, container_id, object_key, expiration=3600, range=[]): return presign(bucket, str(container_id)+"/"+object_key.lstrip('/'), expiration, range)
def upload_file(bucket, container_id, object_key, local_file_path)
-
Upload a file to an S3
bucket
using a given platformContainer
id to a targetobject_key
, usinglocal_file_path
as the source file to uploadArgs
bucket
:str
- The target S3 bucket
container_id
:int
- A platform
Container
id object_key
:str
- The target S3 object key
local_file_path
:str
- The local file to use as the file source to upload to S3
Expand source code
def upload_file(bucket, container_id, object_key, local_file_path): """Upload a file to an S3 `bucket` using a given platform `Container` id to a target `object_key`, using `local_file_path` as the source file to upload Args: bucket (str): The target S3 bucket container_id (int): A platform `Container` id object_key (str): The target S3 object key local_file_path (str): The local file to use as the file source to upload to S3 """ upload_stream(bucket, container_id, object_key, open(local_file_path, 'rb'))
def upload_storage_container_file(storage, container, object_key, local_file_path)
-
Upload a file to S3 using a given platform
Storage
andContainer
object to a targetobject_key
, usinglocal_file_path
as the source file to uploadArgs
storage
:libnova.common.api.Storage
- A platform
Storage
object container
:libnova.common.api.Container
- A platform
Container
object object_key
:str
- The target S3 object key
local_file_path
:str
- The local file to use as the file source to upload to S3
Expand source code
def upload_storage_container_file(storage, container, object_key, local_file_path): """Upload a file to S3 using a given platform `Storage` and `Container` object to a target `object_key`, using `local_file_path` as the source file to upload Args: storage (libnova.common.api.Storage): A platform `Storage` object container (libnova.common.api.Container): A platform `Container` object object_key (str): The target S3 object key local_file_path (str): The local file to use as the file source to upload to S3 """ upload_file(storage.extra_data["bucket"], container.id, object_key, local_file_path)
def upload_storage_container_stream(storage, container, object_key, stream)
-
Upload a file to S3 using a given platform
Storage
andContainer
object to a targetobject_key
, usingstream
as the data source to uploadArgs
storage
:libnova.common.api.Storage
- A platform
Storage
object container
:libnova.common.api.Container
- A platform
Container
object object_key
:str
- The target S3 object key
stream
:io.RawIOBase
- The stream to use as data source
Expand source code
def upload_storage_container_stream(storage, container, object_key, stream): """Upload a file to S3 using a given platform `Storage` and `Container` object to a target `object_key`, using `stream` as the data source to upload Args: storage (libnova.common.api.Storage): A platform `Storage` object container (libnova.common.api.Container): A platform `Container` object object_key (str): The target S3 object key stream (io.RawIOBase): The stream to use as data source """ upload_stream(storage.extra_data["bucket"], container.id, object_key, stream)
def upload_stream(bucket, container_id, object_key, stream)
-
Upload a file to an S3
bucket
using a given platformContainer
id to a targetobject_key
, usingstream
as the data source to uploadArgs
bucket
:str
- The target S3 bucket
container_id
:int
- A platform
Container
id object_key
:str
- The target S3 object key
stream
:io.RawIOBase
- The stream to use as data source
Expand source code
def upload_stream(bucket, container_id, object_key, stream): """Upload a file to an S3 `bucket` using a given platform `Container` id to a target `object_key`, using `stream` as the data source to upload Args: bucket (str): The target S3 bucket container_id (int): A platform `Container` id object_key (str): The target S3 object key stream (io.RawIOBase): The stream to use as data source """ __upload_stream(bucket, str(container_id) + '/' + object_key.lstrip("/"), stream)