def info(self): """ function returns information about the downloaded object. Returns ------- Object """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_download_info.argtypes = [ ctypes.POINTER(_DownloadStruct) ] self.uplink.m_libuplink.uplink_download_info.restype = _ObjectResult # # get last download info by calling the exported golang function object_result = self.uplink.m_libuplink.uplink_download_info( self.download) # # if error occurred if bool(object_result.error): raise _storj_exception( object_result.error.contents.code, object_result.error.contents.message.decode("utf-8")) return self.uplink.object_from_result(object_result.object)
def override_encryption_key(self, bucket_name: str, prefix: str, encryption_key): """ function overrides the root encryption key for the prefix in bucket with encryptionKey. This function is useful for overriding the encryption key in user-specific access grants when implementing multitenancy in a single app bucket. Returns ------- None """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_access_override_encryption_key.argtypes =\ [ctypes.POINTER(_AccessStruct), ctypes.c_char_p, ctypes.c_char_p, ctypes.POINTER(_EncryptionKeyStruct)] self.uplink.m_libuplink.uplink_access_override_encryption_key.restype =\ _EncryptionKeyResult # # prepare the input for the function bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) prefix_ptr = ctypes.c_char_p(prefix.encode('utf-8')) # salted encryption key by calling the exported golang function error_result = self.uplink.m_libuplink.\ uplink_access_override_encryption_key(self.access, bucket_name_ptr, prefix_ptr, encryption_key) # # if error occurred if bool(error_result): raise _storj_exception( error_result.contents.code, error_result.contents.message.decode("utf-8"))
def file_size(self): """ function returns the size of object on Storj network for which download has been created. Returns ------- int """ # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_stat_object.argtypes = [ ctypes.POINTER(_ProjectStruct), ctypes.c_char_p, ctypes.c_char_p ] self.uplink.m_libuplink.uplink_stat_object.restype = _ObjectResult # # get object information by calling the exported golang function object_result = self.uplink.m_libuplink.uplink_stat_object( self.project, self.bucket_name, self.storj_path) # if error occurred if bool(object_result.error): raise _storj_exception( object_result.error.contents.code, object_result.error.contents.message.decode("utf-8")) # find object size return int(object_result.object.contents.system.content_length)
def delete_object(self, bucket_name: str, storj_path: str): """ function deletes the object at the specific key. Parameters ---------- bucket_name : str storj_path : str Returns ------- Object """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_delete_object.argtypes = [ ctypes.POINTER(_ProjectStruct), ctypes.c_char_p, ctypes.c_char_p ] self.uplink.m_libuplink.uplink_delete_object.restype = _ObjectResult # # prepare the input for the function bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) storj_path_ptr = ctypes.c_char_p(storj_path.encode('utf-8')) # delete object by calling the exported golang function object_result = self.uplink.m_libuplink.uplink_delete_object( self.project, bucket_name_ptr, storj_path_ptr) # # if error occurred if bool(object_result.error): raise _storj_exception( object_result.error.contents.code, object_result.error.contents.message.decode("utf-8")) return self.uplink.object_from_result(object_result.object)
def delete_bucket(self, bucket_name: str): """ function deletes a bucket. When bucket is not empty it throws BucketNotEmptyError exception. Parameters ---------- bucket_name : str Returns ------- Bucket """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_delete_bucket.argtypes = [ ctypes.POINTER(_ProjectStruct), ctypes.c_char_p ] self.uplink.m_libuplink.uplink_delete_bucket.restype = _BucketResult # # prepare the input for the function bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) # delete bucket by calling the exported golang function bucket_result = self.uplink.m_libuplink.uplink_delete_bucket( self.project, bucket_name_ptr) # # if error occurred if bool(bucket_result.error): raise _storj_exception( bucket_result.error.contents.code, bucket_result.error.contents.message.decode("utf-8")) return self.uplink.bucket_from_result(bucket_result.bucket)
def serialize(self): """ function serializes an access grant such that it can be used later with ParseAccess or other tools. Returns ------- String """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_access_serialize.argtypes = [ ctypes.POINTER(_AccessStruct) ] self.uplink.m_libuplink.uplink_access_serialize.restype = _StringResult # # get serialized access by calling the exported golang function string_result = self.uplink.m_libuplink.uplink_access_serialize( self.access) # # if error occurred if bool(string_result.error): raise _storj_exception( string_result.error.contents.code, string_result.error.contents.message.decode("utf-8")) return string_result.string.decode("utf-8")
def config_open_project(self, config: Config): """ function opens Storj(V3) project using access grant and custom configuration. Parameters ---------- config : Config Returns ------- Project """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_config_open_project.argtypes =\ [_ConfigStruct, ctypes.POINTER(_AccessStruct)] self.uplink.m_libuplink.uplink_config_open_project.restype = _ProjectResult # # prepare the input for the function if config is None: config_obj = _ConfigStruct() else: config_obj = config.get_structure() # # open project by calling the exported golang function project_result = self.uplink.m_libuplink.uplink_config_open_project( config_obj, self.access) # # if error occurred if bool(project_result.error): raise _storj_exception( project_result.error.contents.code, project_result.error.contents.message.decode("utf-8")) return Project(project_result.project, self.uplink)
def open_project(self): """ function opens Storj(V3) project using access grant. Returns ------- Project """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_open_project.argtypes = [ ctypes.POINTER(_AccessStruct) ] self.uplink.m_libuplink.uplink_open_project.restype = _ProjectResult # # open project by calling the exported golang function project_result = self.uplink.m_libuplink.uplink_open_project( self.access) # # if error occurred if bool(project_result.error): raise _storj_exception( project_result.error.contents.code, project_result.error.contents.message.decode("utf-8")) return Project(project_result.project, self.uplink)
def set_custom_metadata(self, custom_metadata: CustomMetadata = None): """ function to set custom meta information while uploading data Parameters ---------- custom_metadata : CustomMetadata Returns ------- None """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_upload_set_custom_metadata.argtypes = [ctypes.POINTER(_UploadStruct), _CustomMetadataStruct] self.uplink.m_libuplink.uplink_upload_set_custom_metadata.restype = ctypes.POINTER(_Error) # # prepare the input for the function if custom_metadata is None: custom_metadata_obj = _CustomMetadataStruct() else: custom_metadata_obj = custom_metadata.get_structure() # # set custom metadata to upload by calling the exported golang function error = self.uplink.m_libuplink.uplink_upload_set_custom_metadata(self.upload, custom_metadata_obj) # # if error occurred if bool(error): raise _storj_exception(error.contents.code, error.contents.message.decode("utf-8"))
def ensure_bucket(self, bucket_name: str): """ function ensures that a bucket exists or creates a new one. When bucket already exists it returns a valid Bucket and no error Parameters ---------- bucket_name : str Returns ------- Bucket """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_ensure_bucket.argtypes = [ ctypes.POINTER(_ProjectStruct), ctypes.c_char_p ] self.uplink.m_libuplink.uplink_ensure_bucket.restype = _BucketResult # # prepare the input for the function bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) # open bucket if doesn't exist by calling the exported golang function bucket_result = self.uplink.m_libuplink.uplink_ensure_bucket( self.project, bucket_name_ptr) # # if error occurred if bool(bucket_result.error): raise _storj_exception( bucket_result.error.contents.code, bucket_result.error.contents.message.decode("utf-8")) return self.uplink.bucket_from_result(bucket_result.bucket)
def write(self, data_to_write: bytes, size_to_write: int): """ function uploads bytes data passed as parameter to the object's data stream. Parameters ---------- data_to_write : bytes size_to_write : int Returns ------- int """ # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_upload_write.argtypes = [ctypes.POINTER(_UploadStruct), ctypes.POINTER(ctypes.c_uint8), ctypes.c_size_t] self.uplink.m_libuplink.uplink_upload_write.restype = _WriteResult # # prepare the inputs for the function # -------------------------------------------- # data conversion to type required by function # get size of data in c type int32 variable # conversion of read bytes data to c type ubyte Array data_to_write = (ctypes.c_uint8 * ctypes.c_int32(len(data_to_write)).value)(*data_to_write) # conversion of c type ubyte Array to LP_c_ubyte required by upload write function data_to_write_ptr = ctypes.cast(data_to_write, ctypes.POINTER(ctypes.c_uint8)) # -------------------------------------------- size_to_write_obj = ctypes.c_size_t(size_to_write) # upload data by calling the exported golang function write_result = self.uplink.m_libuplink.uplink_upload_write(self.upload, data_to_write_ptr, size_to_write_obj) # # if error occurred if bool(write_result.error): _storj_exception(write_result.error.contents.code, write_result.error.contents.message.decode("utf-8")) return int(write_result.bytes_written)
def config_request_access_with_passphrase(self, config: Config, satellite: str, api_key: str, passphrase: str): """ RequestAccessWithPassphrase generates a new access grant using a passhprase and custom configuration. It must talk to the Satellite provided to get a project-based salt for deterministic key derivation. Note: this is a CPU-heavy function that uses a password-based key derivation function (Argon2). This should be a setup-only step. Most common interactions with the library should be using a serialized access grant through ParseAccess directly. Parameters ---------- config: Config satellite : str api_key : str passphrase : str Returns ------- Access """ # # declare types of arguments and response of the corresponding golang function self.m_libuplink.uplink_config_request_access_with_passphrase.argtypes = [ _ConfigStruct, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p ] self.m_libuplink.uplink_config_request_access_with_passphrase.restype = _AccessResult # # prepare the input for the function if config is None: config_obj = _ConfigStruct() else: config_obj = config.get_structure() satellite_ptr = ctypes.c_char_p(satellite.encode('utf-8')) api_key_ptr = ctypes.c_char_p(api_key.encode('utf-8')) phrase_ptr = ctypes.c_char_p(passphrase.encode('utf-8')) # get access to Storj by calling the exported golang function access_result = self.m_libuplink.uplink_config_request_access_with_passphrase( config_obj, satellite_ptr, api_key_ptr, phrase_ptr) # # if error occurred if bool(access_result.error): raise _storj_exception( access_result.error.contents.code, access_result.error.contents.message.decode("utf-8")) return Access(access_result.access, self)
def read(self, size_to_read: int): """ function downloads up to len size_to_read bytes from the object's data stream. It returns the data_read in bytes and number of bytes read Parameters ---------- size_to_read : int Returns ------- bytes, int """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_download_read.argtypes = [ ctypes.POINTER(_DownloadStruct), ctypes.POINTER(ctypes.c_uint8), ctypes.c_size_t ] self.uplink.m_libuplink.uplink_download_read.restype = _ReadResult # # prepare the inputs for the function data_size = ctypes.c_int32(size_to_read) data_to_write = [0] data_to_write = (ctypes.c_uint8 * data_size.value)(*data_to_write) data_to_write_ptr = ctypes.cast(data_to_write, ctypes.POINTER(ctypes.c_uint8)) size_to_read = ctypes.c_size_t(size_to_read) # read data from Storj by calling the exported golang function read_result = self.uplink.m_libuplink.uplink_download_read( self.download, data_to_write_ptr, size_to_read) # # if error occurred if bool(read_result.error): raise _storj_exception( read_result.error.contents.code, read_result.error.contents.message.decode("utf-8")) data_read = bytes() if int(read_result.bytes_read) != 0: # # -------------------------------------------- # data conversion to type python readable form # conversion of LP_c_ubyte to python readable data variable data_read = ctypes.string_at(data_to_write_ptr, int(read_result.bytes_read)) return data_read, int(read_result.bytes_read)
def download_object(self, bucket_name: str, storj_path: str, download_options: DownloadOptions = None): """ function starts download to the specified key. Parameters ---------- bucket_name : str storj_path : str download_options : DownloadOptions (optional) Returns ------- Download """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_download_object.argtypes =\ [ctypes.POINTER(_ProjectStruct), ctypes.c_char_p, ctypes.c_char_p, ctypes.POINTER(_DownloadOptionsStruct)] self.uplink.m_libuplink.uplink_download_object.restype = _DownloadResult # # prepare the input for the function if download_options is None: download_options_obj = ctypes.POINTER(_DownloadOptionsStruct)() else: download_options_obj = ctypes.byref( download_options.get_structure()) bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) storj_path_ptr = ctypes.c_char_p(storj_path.encode('utf-8')) # get downloader by calling the exported golang function download_result = self.uplink.m_libuplink.uplink_download_object( self.project, bucket_name_ptr, storj_path_ptr, download_options_obj) # # if error occurred if bool(download_result.error): raise _storj_exception( download_result.error.contents.code, download_result.error.contents.message.decode("utf-8")) return Download(download_result.download, self.uplink, self.project, bucket_name_ptr, storj_path_ptr)
def close(self): """ function closes the download. Returns ------- None """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_close_download.argtypes = [ctypes.POINTER(_DownloadStruct)] self.uplink.m_libuplink.uplink_close_download.restype = ctypes.POINTER(_Error) # # close downloader by calling the exported golang function error = self.uplink.m_libuplink.uplink_close_download(self.download) # # if error occurred if bool(error): raise _storj_exception(error.contents.code, error.contents.message.decode("utf-8"))
def abort(self): """ function aborts an ongoing upload. Returns ------- None """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_upload_abort.argtypes = [ctypes.POINTER(_UploadStruct)] self.uplink.m_libuplink.uplink_upload_abort.restype = ctypes.POINTER(_Error) # # abort ongoing upload by calling the exported golang function error = self.uplink.m_libuplink.uplink_upload_abort(self.upload) # # if error occurred if bool(error): raise _storj_exception(error.contents.code, error.contents.message.decode("utf-8"))
def close(self): """ function closes the project and all associated resources. Returns ------- None """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_close_project.argtypes = [ ctypes.POINTER(_ProjectStruct) ] self.uplink.m_libuplink.uplink_close_project.restype = ctypes.POINTER( _Error) # # close Storj project by calling the exported golang function error = self.uplink.m_libuplink.uplink_close_project(self.project) # # if error occurred if bool(error): raise _storj_exception(error.contents.code, error.contents.message.decode("utf-8"))
def derive_encryption_key(self, passphrase: str, salt: str): """ function derives a salted encryption key for passphrase using the salt. This function is useful for deriving a salted encryption key for users when implementing multitenancy in a single app bucket. Returns ------- EncryptionKey """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_derive_encryption_key.argtypes = [ ctypes.c_char_p, ctypes.c_void_p, ctypes.c_size_t ] self.uplink.m_libuplink.uplink_derive_encryption_key.restype = _EncryptionKeyResult # # prepare the input for the function passphrase_ptr = ctypes.c_char_p(passphrase.encode('utf-8')) hash_value = hashlib.sha256() # Choose SHA256 and update with bytes hash_value.update(bytes(salt)) salt_ptr = ctypes.c_void_p(hash_value.hexdigest()) length_ptr = ctypes.c_size_t(hash_value.digest_size) # salted encryption key by calling the exported golang function encryption_key_result = self.uplink.m_libuplink.uplink_derive_encryption_key( passphrase_ptr, salt_ptr, length_ptr) # # if error occurred if bool(encryption_key_result.error): raise _storj_exception( encryption_key_result.error.contents.code, encryption_key_result.error.contents.message.decode("utf-8")) return encryption_key_result.encryption_key
def parse_access(self, serialized_access: str): """ ParseAccess parses a serialized access grant string. This should be the main way to instantiate an access grant for opening a project. See the note on RequestAccessWithPassphrase Parameters ---------- serialized_access : str Returns ------- Access """ # # prepare the input for the function serialized_access_ptr = ctypes.c_char_p( serialized_access.encode('utf-8')) # # declare types of arguments and response of the corresponding golang function self.m_libuplink.uplink_parse_access.argtypes = [ctypes.c_char_p] self.m_libuplink.uplink_parse_access.restype = _AccessResult # # get parsed access by calling the exported golang function access_result = self.m_libuplink.uplink_parse_access( serialized_access_ptr) # # if error occurred if bool(access_result.error): raise _storj_exception( access_result.error.contents.code, access_result.error.contents.message.decode("utf-8")) return Access(access_result.access, self)
def share(self, permission: Permission = None, shared_prefix: [SharePrefix] = None): """ function Share creates a new access grant with specific permissions. Access grants can only have their existing permissions restricted, and the resulting access grant will only allow for the intersection of all previous Share calls in the access grant construction chain. Prefixes, if provided, restrict the access grant (and internal encryption information) to only contain enough information to allow access to just those prefixes. Parameters ---------- permission : Permission shared_prefix : list of SharePrefix Returns ------- Access """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_access_share.argtypes = [ ctypes.POINTER(_AccessStruct), _PermissionStruct, ctypes.POINTER(_SharePrefixStruct), ctypes.c_size_t ] self.uplink.m_libuplink.uplink_access_share.restype = _AccessResult # # prepare the input for the function # check and create valid _PermissionStruct parameter if permission is None: permission_obj = _PermissionStruct() else: permission_obj = permission.get_structure() # check and create valid Share Prefix parameter if shared_prefix is None: shared_prefix_obj = ctypes.POINTER(_SharePrefixStruct)() array_size = ctypes.c_size_t(0) else: num_of_structs = len(shared_prefix) li_array_size = (_SharePrefixStruct * num_of_structs)() array = ctypes.cast(li_array_size, ctypes.POINTER(_SharePrefixStruct)) for i, val in enumerate(shared_prefix): array[i] = val.get_structure() shared_prefix_obj = array array_size = ctypes.c_size_t(num_of_structs) # # get shareable access by calling the exported golang function access_result = self.uplink.m_libuplink.uplink_access_share( self.access, permission_obj, shared_prefix_obj, array_size) # # if error occurred if bool(access_result.error): raise _storj_exception( access_result.error.contents.code, access_result.error.contents.message.decode("utf-8")) return Access(access_result.access, self.uplink)
def list_objects(self, bucket_name: str, list_object_options: ListObjectsOptions = None): """ function returns a list of objects with all its information. Parameters ---------- bucket_name : str list_object_options : ListObjectsOptions (optional) Returns ------- list of Object """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_list_objects.argtypes =\ [ctypes.POINTER(_ProjectStruct), ctypes.c_char_p, ctypes.POINTER(_ListObjectsOptionsStruct)] self.uplink.m_libuplink.uplink_list_objects.restype =\ ctypes.POINTER(_ObjectIterator) # self.uplink.m_libuplink.uplink_object_iterator_item.argtypes =\ [ctypes.POINTER(_ObjectIterator)] self.uplink.m_libuplink.uplink_object_iterator_item.restype =\ ctypes.POINTER(_ObjectStruct) # self.uplink.m_libuplink.uplink_object_iterator_err.argtypes =\ [ctypes.POINTER(_ObjectIterator)] self.uplink.m_libuplink.uplink_object_iterator_err.restype =\ ctypes.POINTER(_Error) # self.uplink.m_libuplink.uplink_object_iterator_next.argtypes =\ [ctypes.POINTER(_ObjectIterator)] self.uplink.m_libuplink.uplink_object_iterator_next.restype =\ ctypes.c_bool # # prepare the input for the function if list_object_options is None: list_object_options_obj = ctypes.POINTER( _ListObjectsOptionsStruct)() else: list_object_options_obj = ctypes.byref( list_object_options.get_structure()) bucket_name_ptr = ctypes.c_char_p(bucket_name.encode('utf-8')) # get object list by calling the exported golang function object_iterator = self.uplink.m_libuplink.uplink_list_objects( self.project, bucket_name_ptr, list_object_options_obj) object_iterator_err = self.uplink.m_libuplink.uplink_object_iterator_err( object_iterator) if bool(object_iterator_err): raise _storj_exception( object_iterator_err.contents.code, object_iterator_err.contents.message.decode("utf-8")) object_list = list() while self.uplink.m_libuplink.uplink_object_iterator_next( object_iterator): object_ = self.uplink.m_libuplink.uplink_object_iterator_item( object_iterator) object_list.append(self.uplink.object_from_result(object_)) return object_list
def list_buckets(self, list_bucket_options: ListBucketsOptions = None): """ function returns a list of buckets with all its information. Parameters ---------- list_bucket_options : ListBucketsOptions (optional) Returns ------- list of Bucket """ # # declare types of arguments and response of the corresponding golang function self.uplink.m_libuplink.uplink_list_buckets.argtypes =\ [ctypes.POINTER(_ProjectStruct), ctypes.POINTER(_ListBucketsOptionsStruct)] self.uplink.m_libuplink.uplink_list_buckets.restype =\ ctypes.POINTER(_BucketIterator) # self.uplink.m_libuplink.uplink_bucket_iterator_item.argtypes =\ [ctypes.POINTER(_BucketIterator)] self.uplink.m_libuplink.uplink_bucket_iterator_item.restype =\ ctypes.POINTER(_BucketStruct) # self.uplink.m_libuplink.uplink_bucket_iterator_err.argtypes =\ [ctypes.POINTER(_BucketIterator)] self.uplink.m_libuplink.uplink_bucket_iterator_err.restype =\ ctypes.POINTER(_Error) # self.uplink.m_libuplink.uplink_bucket_iterator_next.argtypes =\ [ctypes.POINTER(_BucketIterator)] self.uplink.m_libuplink.uplink_bucket_iterator_next.restype =\ ctypes.c_bool # # prepare the input for the function if list_bucket_options is None: list_bucket_options_obj = ctypes.POINTER( _ListBucketsOptionsStruct)() else: list_bucket_options_obj = ctypes.byref( list_bucket_options.get_structure()) # get bucket list by calling the exported golang function bucket_iterator = self.uplink.m_libuplink.uplink_list_buckets( self.project, list_bucket_options_obj) bucket_iterator_err = self.uplink.m_libuplink.uplink_bucket_iterator_err( bucket_iterator) if bool(bucket_iterator_err): raise _storj_exception( bucket_iterator_err.contents.code, bucket_iterator_err.contents.message.decode("utf-8")) bucket_list = list() while self.uplink.m_libuplink.uplink_bucket_iterator_next( bucket_iterator): bucket = self.uplink.m_libuplink.uplink_bucket_iterator_item( bucket_iterator) bucket_list.append(self.uplink.bucket_from_result(bucket)) return bucket_list