def create_account(user, account_name, description=None, accounting_service=None, accounting_url=None): """Create an account on the accounting service for the passed user, calling the account 'account_name' and optionally passing in an account description. Note that the user must have authorised the login Args: user (User): User to create account for account_name (str): Name of account to create accounting_service (Service, default=None): Accounting service on which to create account accounting_url (str, default=None): Accounting URL Returns: Account: New account """ if accounting_service is None: service = _get_accounting_service(accounting_url) else: if not accounting_service.is_accounting_service(): raise TypeError("You can only query account using " "a valid accounting service") service = accounting_service if not user.is_logged_in(): raise PermissionError( "You cannot create an account called '%s' for user " "'%s' as the user login has not been authenticated." % (account_name, user.name())) from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation(user=user, resource="create_account %s" % account_name) args = { "account_name": str(account_name), "authorisation": authorisation.to_data() } if description is None: args["description"] = "Account '%s' for '%s'" % \ (str(account_name), user.name()) else: args["description"] = str(description) result = service.call_function(function="create_account", args=args) account_uid = result["account_uid"] account = Account() account._account_name = account_name account._account_uid = account_uid account._user = user account._accounting_service = service return account
def logout(self): """Log out from the current session""" if self.is_logged_in() or self.is_logging_in(): service = self.identity_service() args = {"session_uid": self._session_uid} if self.is_logged_in(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation( resource="logout %s" % self._session_uid, user=self) args["authorisation"] = authorisation.to_data() else: # we are not fully logged in so cannot generate an # authorisation for the logout from Acquire.ObjectStore import bytes_to_string \ as _bytes_to_string resource = "logout %s" % self._session_uid signature = self.signing_key().sign(resource) args["signature"] = _bytes_to_string(signature) result = service.call_function(function="logout", args=args) self._status = _LoginStatus.LOGGED_OUT return result
def refund(self, credit_note): """Refunds the passed credit note that contained a transfer of from another account to the passed account Args: credit_note (CreditNote): Credit note to refund Returns: TransactionRecord: Record of this transaction """ if not self.is_logged_in(): raise PermissionError("You cannot refund a credit note as the " "user has not yet logged in!") if credit_note.account_uid() != self.uid(): raise ValueError( "You cannot refund a transaction from a different " "account! %s versus %s" % (credit_note.account_uid(), self.uid())) from Acquire.Client import Authorisation as _Authorisation from Acquire.Accounting import create_decimal as _create_decimal service = self.accounting_service() auth = _Authorisation(resource=self._account_uid, user=self._user) args = {"credit_note": credit_note.to_data(), "authorisation": auth.to_data()} result = service.call_function(function="refund", args=args) return result["transaction_record"]
def _get_account_uids(user, accounting_service=None, accounting_url=None): """Return the names and UIDs of all of the accounts that belong to the passed user on the passed accounting_service Args: user (User): User for query accounting_service (Service, default=None): Accounting service to check accounting_url (str, default=None): Accounting URL Returns: list: Names and UIDs of accounts belonging to passed user on passed service """ if accounting_service is None: service = _get_accounting_service(accounting_url) else: if not accounting_service.is_accounting_service(): raise TypeError("You can only query accounts using " "a valid accounting service") service = accounting_service if not user.is_logged_in(): raise PermissionError( "You can only get information about about a user's accounts " "if they have authenticated their login") from Acquire.Client import Authorisation as _Authorisation auth = _Authorisation(user=user, resource="get_account_uids") args = {"authorisation": auth.to_data()} result = service.call_function(function="get_account_uids", args=args) return result["account_uids"]
def _refresh(self, force_update=False): """Refresh the current status of this account. This fetches the latest data, e.g. balance, limits etc. Note that this limits you to refreshing at most once every five seconds... Args: force_update (bool, default=False): Force the refresh Returns: None """ if self.is_null(): from Acquire.Accounting import create_decimal as _create_decimal from Acquire.Accounting import Balance as _Balance self._overdraft_limit = _create_decimal(0) self._balance = _Balance() return if force_update: should_refresh = True else: should_refresh = False if self._last_update is None: should_refresh = True else: should_refresh = (_datetime.datetime.now() - self._last_update).seconds > 5 if not should_refresh: return if not self.is_logged_in(): raise PermissionError( "You cannot get information about this account " "until after the owner has successfully authenticated.") from Acquire.Client import Authorisation as _Authorisation from Acquire.Accounting import create_decimal as _create_decimal service = self.accounting_service() auth = _Authorisation(resource="get_info %s" % self._account_uid, user=self._user) args = { "authorisation": auth.to_data(), "account_name": self.name(), "account_uid": self.uid() } result = service.call_function(function="get_info", args=args) from Acquire.Accounting import Balance as _Balance self._balance = _Balance.from_data(result["balance"]) self._overdraft_limit = _create_decimal(result["overdraft_limit"]) self._description = result["description"] self._last_update = _datetime.datetime.now()
def perform(self, transaction, credit_account, is_provisional=False): """Tell this accounting service to apply the transfer described in 'transaction' from this account to the passed account. Note that the user must have logged into this account so that they have authorised this transaction. This returns the record of this transaction Args: transaction (Transaction): Transaction to perform credit_account (Account): Account to credit is_provisional (bool, default=False): Is transaction provisional """ if not self.is_logged_in(): raise PermissionError("You cannot transfer value from '%s' to " "'%s' because you have not authenticated " "the user who owns this account" % (str(self), str(credit_account))) from Acquire.Accounting import Transaction as _Transaction if not isinstance(transaction, _Transaction): raise TypeError("The passed transaction must be of type " "Transaction") if not isinstance(credit_account, Account): raise TypeError("The passed credit account must be of type " "Account") if transaction.is_null(): return None from Acquire.Client import Authorisation as _Authorisation service = self.accounting_service() auth = _Authorisation(resource=transaction.fingerprint(), user=self._user) if is_provisional: is_provisional = True else: is_provisional = False args = { "transaction": transaction.to_data(), "debit_account_uid": str(self.uid()), "credit_account_uid": str(credit_account.uid()), "is_provisional": is_provisional, "authorisation": auth.to_data() } result = service.call_function(function="perform", args=args) return result["transaction_records"]
def list_versions(self, include_metadata=False): """Return a list of all of the versions of this file. If 'include_metadata' is True then this will include the full metadata of every version """ if self.is_null(): return [] if self._creds is None: raise PermissionError( "Cannot list versions of this file as it has not " "been properly opened") drive_uid = self._metadata.drive().uid() if include_metadata: include_metadata = True else: include_metadata = False filename = self._metadata.name() args = {"drive_uid": drive_uid, "include_metadata": include_metadata, "filename": filename} if self._creds.is_user(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation( resource="list_versions %s" % filename, user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() storage_service = self._creds.storage_service() response = storage_service.call_function(function="list_versions", args=args) from Acquire.ObjectStore import string_to_list \ as _string_to_list from Acquire.Storage import FileMeta as _FileMeta versions = _string_to_list(response["versions"], _FileMeta) for version in versions: version._copy_credentials(self._metadata) return versions
def chunk_download(self, filename=None, version=None, dir=None): """Return a ChunkDownloader to download this file chunk-by-chunk """ if self.is_null(): raise PermissionError("Cannot download a null File!") if self._creds is None: raise PermissionError("We have not properly opened the file!") if filename is None: filename = self._metadata.name() drive_uid = self._metadata.drive().uid() if self._creds.is_user(): privkey = self._creds.user().session_key() else: from Acquire.Crypto import get_private_key as _get_private_key privkey = _get_private_key("parkey") args = {"drive_uid": drive_uid, "filename": self._metadata.name(), "encryption_key": privkey.public_key().to_data(), "must_chunk": True} if self._creds.is_user(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation( resource="download %s %s" % (drive_uid, self._metadata.name()), user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() storage_service = self._creds.storage_service() response = storage_service.call_function( function="download", args=args) from Acquire.Client import ChunkDownloader as _ChunkDownloader downloader = _ChunkDownloader.from_data(response["downloader"], privkey=privkey, service=storage_service) downloader._start_download(filename=filename, dir=dir) return downloader
def _get_drive(creds, name=None, drive_uid=None, aclrules=None, autocreate=True): """Return the drive called 'name' using the passed credentials. The name will default to 'main' if it is not set, and the drive will be created automatically is 'autocreate' is True and the drive does not exist. If the drive is created, it would be created with the passed aclrules, if specified (this will be user-owner-only if not specified) """ storage_service = creds.storage_service() if drive_uid is None: if name is None: name = "main" else: name = str(name) if autocreate: autocreate = True else: autocreate = False else: name = None autocreate = False drive_uid = str(drive_uid) args = {"name": name, "autocreate": autocreate, "drive_uid": drive_uid} if aclrules is not None: args["aclrules"] = aclrules.to_data() if creds.is_user(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation(resource="UserDrives", user=creds.user()) args["authorisation"] = authorisation.to_data() elif creds.is_par(): par = creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = creds.secret() response = storage_service.call_function(function="open_drive", args=args) from Acquire.Client import DriveMeta as _DriveMeta return _create_drive(creds=creds, metadata=_DriveMeta.from_data(response["drive"]))
def deposit(user, value, description=None, account_name=None, accounting_service=None, accounting_url=None): """Tell the system to allow the user to deposit 'value' from their (real) financial account to the system accounts Args: user (User): User to authorise value (Decimal): Value to deposit description (str): Description of deposit accounting_service (Service, default=None): Accounting service to make deposit accounting_url (str): Accounting URl Returns: TODO - return value here """ if accounting_service is None: service = _get_accounting_service(accounting_url) else: if not accounting_service.is_accounting_service(): raise TypeError("You can only deposit funds using an " "accounting service!") service = accounting_service if description is None: description = "Deposit" from Acquire.Accounting import Transaction as _Transaction transaction = _Transaction(value=value, description=description) from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation(user=user, resource=transaction.fingerprint()) args = { "authorisation": authorisation.to_data(), "transaction": transaction.to_data() } if account_name: args["account_name"] = str(account_name) result = service.call_function(function="deposit", args=args) return result
def list_files(self, dir=None, filename=None, include_metadata=False): """Return a list of the FileMetas of all of the files contained in this drive. If 'dir' is specified then list only the files that are contained in 'dir'. If 'filename' is specified then return only the files that match the passed filename """ if self.is_null(): return [] from Acquire.ObjectStore import string_to_list as _string_to_list from Acquire.Storage import FileMeta as _FileMeta if include_metadata: include_metadata = True else: include_metadata = False args = { "drive_uid": self._metadata.uid(), "include_metadata": include_metadata } if dir is not None: args["dir"] = str(dir) if filename is not None: args["filename"] = str(filename) if self._creds.is_user(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation(resource="list_files", user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() response = self.storage_service().call_function(function="list_files", args=args) files = _string_to_list(response["files"], _FileMeta) for f in files: f._set_drive_metadata(self._metadata, self._creds) return files
def _get_account_uid(user, account_name, accounting_service=None, accounting_url=None): """Return the UID of the account called 'account_name' that belongs to passed user on the passed accounting_service Args: user (User): User for query account_name (str): Name of account accounting_service (Service, default=None): Accounting service to check accounting_url (str, default=None): Account URL Returns: str: UID of account named 'account_name' """ if account_name is None: # return the UID of the default account for this user account_name = "main" if accounting_service is None: service = _get_accounting_service(accounting_url) else: if not accounting_service.is_accounting_service(): raise TypeError("You can only query accounts using " "a valid accounting service") service = accounting_service args = {"user_guid": user.guid(), "account_name": str(account_name)} if user.is_logged_in(): from Acquire.Client import Authorisation as _Authorisation auth = _Authorisation(user=user, resource="get_account_uids") args["authorisation"] = auth.to_data() result = service.call_function(function="get_account_uids", args=args) account_uids = result["account_uids"] for account_uid in account_uids: if account_uids[account_uid] == account_name: return account_uid from Acquire.Client import AccountError raise AccountError("There is no account called '%s' for '%s'" % (account_name, str(user)))
def set_cluster(cluster, authorisation=None, passphrase=None, user=None): """Function used to set the single compute cluster that is connected to this compute service. This must be authorised by an admin user of this compute service """ if not isinstance(cluster, Cluster): raise TypeError("The cluster must be type Cluster") resource = "set_cluster %s" % cluster.fingerprint() from Acquire.Client import Authorisation as _Authorisation if Cluster._is_running_service(): from Acquire.Service import get_this_service as _get_this_service service = _get_this_service(need_private_access=True) if authorisation is not None: if not isinstance(authorisation, _Authorisation): raise TypeError( "The authorisation must be type Authorisation") service.assert_admin_authorised(authorisation, resource) else: # we are rotating keys, so check the passphrase against # the old passphrase cluster = Cluster.get_cluster() cluster.verify_passphrase(passphrase=passphrase, resource="set_cluster") from Acquire.ObjectStore import ObjectStore as _ObjectStore from Acquire.Service import get_service_account_bucket \ as _get_service_account_bucket bucket = _get_service_account_bucket() key = "compute/cluster" _ObjectStore.set_object_from_json(bucket, key, cluster.to_data()) else: authorisation = _Authorisation(user=user, resource=resource) compute_service = cluster.compute_service() args = {"authorisation": authorisation.to_data(), "cluster": cluster.to_data()} compute_service.call_function(function="set_cluster", args=args)
def _list_drives(creds, drive_uid=None): """Return a list of all of the DriveMetas of the drives accessible at the top-level using the passed credentials, or that are sub-drives of the drive with UID 'drive_uid' """ from Acquire.Client import StorageCreds as _StorageCreds if not isinstance(creds, _StorageCreds): raise TypeError("The passed creds must be type StorageCreds") args = {} if creds.is_user(): if drive_uid is not None: drive_uid = str(drive_uid) from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation(resource="UserDrives", user=creds.user()) args = {"authorisation": authorisation.to_data()} elif creds.is_par(): par = creds.par() par.assert_valid() args["par"] = par.to_data() args["secret"] = creds.secret() if drive_uid is not None: args["drive_uid"] = str(drive_uid) storage_service = creds.storage_service() response = storage_service.call_function(function="list_drives", args=args) from Acquire.ObjectStore import string_to_list as _string_to_list from Acquire.Client import DriveMeta as _DriveMeta drives = _string_to_list(response["drives"], _DriveMeta) for drive in drives: drive._creds = creds return drives
def receipt(self, credit_note, receipted_value=None): """Receipt the passed credit note that contains a request to transfer value from another account to the passed account Args: credit_note (CreditNote): CreditNote to use to create receipt receipted_value (Decimal, default=None): Receipted value Returns: TransactionRecord: Record of this transaction """ if not self.is_logged_in(): raise PermissionError("You cannot receipt a credit note as the " "user has not yet logged in!") if credit_note.account_uid() != self.uid(): raise ValueError( "You cannot receipt a transaction from a different " "account! %s versus %s" % (credit_note.account_uid(), self.uid())) from Acquire.Client import Authorisation as _Authorisation from Acquire.Accounting import create_decimal as _create_decimal service = self.accounting_service() auth = _Authorisation(resource=self._account_uid, user=self._user) args = { "credit_note": credit_note.to_data(), "authorisation": auth.to_data() } if receipted_value is not None: args["receipted_value"] = str(_create_decimal(receipted_value)) result = service.call_function(function="receipt", args=args) return result["transaction_record"]
def authorise(self, resource): """Create an authorisation for the specified resource""" from Acquire.Client import Authorisation as _Authorisation return _Authorisation(user=self, resource=resource)
def download(self, filename=None, version=None, dir=None, force_par=False): """Download this file into the local directory the local directory, or 'dir' if specified, calling the file 'filename' (or whatever it is called on the Drive if not specified). If a local file exists with this name, then a new, unique filename will be used. This returns the local filename of the downloaded file (with full absolute path) Note that this only downloads files for which you have read-access. If the file is not readable then an exception is raised and nothing is returned If 'version' is specified then download a specific version of the file. Otherwise download the version associated with this file object """ if self.is_null(): raise PermissionError("Cannot download a null File!") if self._creds is None: raise PermissionError("We have not properly opened the file!") if filename is None: filename = self._metadata.name() drive_uid = self._metadata.drive().uid() from Acquire.Client import create_new_file as \ _create_new_file if self._creds.is_user(): privkey = self._creds.user().session_key() else: from Acquire.Crypto import get_private_key as _get_private_key privkey = _get_private_key("parkey") args = {"drive_uid": drive_uid, "filename": self._metadata.name(), "encryption_key": privkey.public_key().to_data()} if self._creds.is_user(): from Acquire.Client import Authorisation as _Authorisation authorisation = _Authorisation( resource="download %s %s" % (drive_uid, self._metadata.name()), user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() if force_par: args["force_par"] = True if version is not None: from Acquire.ObjectStore import datetime_to_string \ as _datetime_to_string args["version"] = _datetime_to_string(version) elif self._metadata.version() is not None: args["version"] = self._metadata.version() storage_service = self._creds.storage_service() response = storage_service.call_function( function="download", args=args) from Acquire.Client import FileMeta as _FileMeta filemeta = _FileMeta.from_data(response["filemeta"]) if "filedata" in response: # we have already downloaded the file to 'filedata' filedata = response["filedata"] from Acquire.ObjectStore import string_to_bytes \ as _string_to_bytes filedata = _string_to_bytes(response["filedata"]) del response["filedata"] # validate that the size and checksum are correct filemeta.assert_correct_data(filedata) if filemeta.is_compressed(): # uncompress the data from Acquire.Client import uncompress as _uncompress filedata = _uncompress( inputdata=filedata, compression_type=filemeta.compression_type()) # write the data to the specified local file... filename = _create_new_file(filename=filename, dir=dir) with open(filename, "wb") as FILE: FILE.write(filedata) FILE.flush() elif "download_par" in response: from Acquire.ObjectStore import OSPar as _OSPar filename = _create_new_file(filename=filename, dir=dir) par = _OSPar.from_data(response["download_par"]) par.read(privkey).get_object_as_file(filename) par.close(privkey) # validate that the size and checksum are correct filemeta.assert_correct_data(filename=filename) # uncompress the file if desired if filemeta.is_compressed(): from Acquire.Client import uncompress as _uncompress _uncompress(inputfile=filename, outputfile=filename, compression_type=filemeta.compression_type()) elif "downloader" in response: from Acquire.Client import ChunkDownloader as _ChunkDownloader downloader = _ChunkDownloader.from_data(response["downloader"], privkey=privkey, service=storage_service) filename = downloader.download(filename=filename, dir=dir) filemeta._copy_credentials(self._metadata) self._metadata = filemeta return filename
def chunk_upload(self, aclrules=None): """Start a chunk-upload of a new version of this file. This will return a chunk-uploader that can be used to upload a file chunk-by-chunk """ if self.is_null(): raise PermissionError("Cannot download a null File!") if self._creds is None: raise PermissionError("We have not properly opened the file!") from Acquire.Client import Authorisation as _Authorisation from Acquire.ObjectStore import OSPar as _OSPar from Acquire.Client import FileMeta as _FileMeta uploaded_name = self._metadata.filename() drive_uid = self._metadata.drive().uid() args = {"filename": uploaded_name, "drive_uid": drive_uid} if aclrules is not None: args["aclrules"] = aclrules.to_data() if self._creds.is_user(): authorisation = _Authorisation( resource="chunk_upload %s" % uploaded_name, user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() else: raise PermissionError( "Either a logged-in user or valid PAR must be provided!") if self._creds.is_user(): privkey = self._creds.user().session_key() else: from Acquire.Crypto import get_private_key \ as _get_private_key privkey = _get_private_key("parkey") args["encryption_key"] = privkey.public_key().to_data() # will eventually need to authorise payment... storage_service = self._creds.storage_service() response = storage_service.call_function( function="open_uploader", args=args) filemeta = _FileMeta.from_data(response["filemeta"]) filemeta._set_drive_metadata(self._metadata._drive_metadata, self._creds) self._metadata = filemeta from Acquire.Client import ChunkUploader as _ChunkUploader return _ChunkUploader.from_data(response["uploader"], privkey=privkey, service=storage_service)
def __init__(self, location=None, user=None, aclrule=None, expires_datetime=None): """Construct a PAR for the specified location, authorised by the passed user, giving permissions according to the passed 'aclrule' (default is ACLRule.reader()). The passed 'expires_datetime' is the time at which this PAR will expire (by default within 24 hours) """ self._location = None self._uid = None self._expires_datetime = None if location is None: return from Acquire.Client import Location as _Location if not isinstance(location, _Location): raise TypeError("The location must be type Location") if location.is_null(): return from Acquire.Client import User as _User if not isinstance(user, _User): raise TypeError("The user must be type User") if not user.is_logged_in(): raise PermissionError("The passed User must be logged in!") from Acquire.Client import ACLRule as _ACLRule if aclrule is None: aclrule = _ACLRule.reader() elif not isinstance(aclrule, _ACLRule): raise TypeError("The aclrule must be type ACLRule") if expires_datetime is None: from Acquire.ObjectStore import get_datetime_future \ as _get_datetime_future expires_datetime = _get_datetime_future(days=1) else: from Acquire.ObjectStore import datetime_to_datetime \ as _datetime_to_datetime expires_datetime = _datetime_to_datetime(expires_datetime) self._location = location self._expires_datetime = expires_datetime self._aclrule = aclrule from Acquire.Client import Authorisation as _Authorisation auth = _Authorisation(user=user, resource="create_par %s" % self.fingerprint()) from Acquire.Crypto import PrivateKey as _PrivateKey self._secret = _PrivateKey.random_passphrase() args = { "authorisation": auth.to_data(), "par": self.to_data(), "secret": self._secret } service = location.service() result = service.call_function(function="create_par", args=args) self._set_uid(result["par_uid"])
def upload(self, filename, force_par=False, aclrules=None): """Upload 'filename' as the new version of this file""" if self.is_null(): raise PermissionError("Cannot download a null File!") if self._creds is None: raise PermissionError("We have not properly opened the file!") from Acquire.Client import Authorisation as _Authorisation from Acquire.ObjectStore import OSPar as _OSPar from Acquire.Client import FileMeta as _FileMeta from Acquire.Storage import FileHandle as _FileHandle local_cutoff = None if force_par: # only upload using a OSPar local_cutoff = 0 uploaded_name = self._metadata.filename() drive_uid = self._metadata.drive().uid() filehandle = _FileHandle(filename=filename, remote_filename=uploaded_name, drive_uid=drive_uid, aclrules=aclrules, local_cutoff=local_cutoff) try: args = {"filehandle": filehandle.to_data()} if self._creds.is_user(): authorisation = _Authorisation( resource="upload %s" % filehandle.fingerprint(), user=self._creds.user()) args["authorisation"] = authorisation.to_data() elif self._creds.is_par(): par = self._creds.par() par.assert_valid() args["par_uid"] = par.uid() args["secret"] = self._creds.secret() else: raise PermissionError( "Either a logged-in user or valid PAR must be provided!") if not filehandle.is_localdata(): # we will need to upload against a OSPar, so need to tell # the service how to encrypt the OSPar... if self._creds.is_user(): privkey = self._creds.user().session_key() else: from Acquire.Crypto import get_private_key \ as _get_private_key privkey = _get_private_key("parkey") args["encryption_key"] = privkey.public_key().to_data() # will eventually need to authorise payment... storage_service = self._creds.storage_service() response = storage_service.call_function( function="upload", args=args) filemeta = _FileMeta.from_data(response["filemeta"]) # if this was a large file, then we will receive a OSPar back # which must be used to upload the file if not filehandle.is_localdata(): par = _OSPar.from_data(response["upload_par"]) par.write(privkey).set_object_from_file( filehandle.local_filename()) par.close(privkey) filemeta._set_drive_metadata(self._metadata._drive_metadata, self._creds) return filemeta except: # ensure that any temporary files are removed filehandle.__del__() raise