docs: def file_put( blockchain_id, hostname, recipient_blockchain_ids, data_name, input_path, passphrase=None, config_path=CONFIG_PATH, wallet_keys=None ):
      """
      Send a file to the given recipient, encrypted and signed with the
      given blockchain ID.
      Allow each recipient to receive the data on each of their hosts.
      Return {'status': True} on success, and upload to cloud storage
      Return {'error': ...} on error
      """
      fd, output_path = tempfile.mkstemp( prefix="blockstack-file-" )
      os.fchmod( fd, 0600 )
      os.close(fd)
  
      config_dir = os.path.dirname(config_path)
      client_config_path = os.path.join(config_dir, blockstack_client.CONFIG_FILENAME )
  
      all_recipients = []
      
      # make available to all other hosts for this blockchain_id
      my_hosts = file_list_hosts( blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
      if 'error' in my_hosts:
          log.error("Failed to list hosts: %s" % my_hosts['error'])
          os.unlink(output_path)
          return {'error': 'Failed to look up sender keys'}
  
      if hostname in my_hosts:
          my_hosts.remove(hostname)
  
      all_recipients += [(blockchain_id, host) for host in my_hosts['hosts']]
  
      # make available to all hosts for each recipient 
      for recipient_blockchain_id in recipient_blockchain_ids:
          their_hosts = file_list_hosts( recipient_blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
          if 'error' in their_hosts:
              log.error("Failed to list hosts for %s: %s" % (recipient_blockchain_id, their_hosts['error']))
              os.unlink(output_path)
              return {'error': 'Failed to look up recipient keys'}
  
          all_recipients += [(recipient_blockchain_id, host) for host in their_hosts['hosts']]
  
      # encrypt
      res = file_encrypt( blockchain_id, hostname, all_recipients, input_path, output_path, passphrase=passphrase, config_path=config_path, wallet_keys=wallet_keys )
      if 'error' in res:
          log.error("Failed to encrypt: %s" % res['error'])
          os.unlink(output_path)
          return {'error': 'Failed to encrypt'}
  
      # load up 
      with open(output_path, "r") as f:
          ciphertext = f.read()
  
      message = {'ciphertext': ciphertext, 'sender_key_id': res['sender_key_id']}
  
      # put to mutable storage 
      fq_data_name = file_fq_data_name( data_name ) 
      proxy = blockstack_client.get_default_proxy( config_path=client_config_path )
  
      res = blockstack_client.data_put( blockstack_client.make_mutable_data_url( blockchain_id, fq_data_name, None ), message, wallet_keys=wallet_keys, proxy=proxy )
      if 'error' in res:
          log.error("Failed to put data: %s" % res['error'])
          os.unlink(output_path)
          return {'error': 'Failed to replicate data'}
  
      os.unlink(output_path)
      return {'status': True}