def _do_config_proposal_vote(args): """Executes the 'proposal vote' subcommand. Given a key file, a proposal id and a vote value, it generates a batch of sawtooth_settings transactions in a BatchList instance. The BatchList is file or submitted to a validator. """ signer = _read_signer(args.key) rest_client = RestClient(args.url) proposals = _get_proposals(rest_client) proposal = None for candidate in proposals.candidates: if candidate.proposal_id == args.proposal_id: proposal = candidate break if proposal is None: raise CliException('No proposal exists with the given id') for vote_record in proposal.votes: if vote_record.public_key == signer.get_public_key().as_hex(): raise CliException( 'A vote has already been recorded with this signing key') txn = _create_vote_txn( signer, args.proposal_id, proposal.proposal.setting, args.vote_value) batch = _create_batch(signer, [txn]) batch_list = BatchList(batches=[batch]) rest_client.send_batches(batch_list)
def _do_config_proposal_create(args): """Executes the 'proposal create' subcommand. Given a key file, and a series of key/value pairs, it generates batches of sawtooth_settings transactions in a BatchList instance. The BatchList is either stored to a file or submitted to a validator, depending on the supplied CLI arguments. """ settings = [s.split('=', 1) for s in args.setting] pubkey, signing_key = _read_signing_keys(args.key) txns = [_create_propose_txn(pubkey, signing_key, setting) for setting in settings] batch = _create_batch(pubkey, signing_key, txns) batch_list = BatchList(batches=[batch]) if args.output is not None: try: with open(args.output, 'wb') as batch_file: batch_file.write(batch_list.SerializeToString()) except IOError as e: raise CliException( 'Unable to write to batch file: {}'.format(str(e))) elif args.url is not None: rest_client = RestClient(args.url) rest_client.send_batches(batch_list) else: raise AssertionError('No target for create set.')
def do_batch_list(args): rest_client = RestClient(args.url, args.user) batches = rest_client.list_batches() keys = ('batch_id', 'txns', 'signer') headers = tuple(k.upper() for k in keys) def parse_batch_row(batch): return ( batch['header_signature'], len(batch.get('transactions', [])), batch['header']['signer_pubkey']) if args.format == 'default': fmt.print_terminal_table(headers, batches, parse_batch_row) elif args.format == 'csv': fmt.print_csv(headers, batches, parse_batch_row) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, parse_batch_row(b))} for b in batches] if args.format == 'yaml': fmt.print_yaml(data) elif args.format == 'json': fmt.print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format))
def _do_config_list(args): """Lists the current on-chain configuration values. """ rest_client = RestClient(args.url) state = rest_client.list_state(subtree=SETTINGS_NAMESPACE) prefix = args.filter head = state['head'] state_values = state['data'] printable_settings = [] proposals_address = _key_to_address('sawtooth.settings.vote.proposals') for state_value in state_values: if state_value['address'] == proposals_address: # This is completely internal setting and we won't list it here continue decoded = b64decode(state_value['data']) setting = Setting() setting.ParseFromString(decoded) for entry in setting.entries: if entry.key.startswith(prefix): printable_settings.append(entry) printable_settings.sort(key=lambda s: s.key) if args.format == 'default': tty_width = tty.width() for setting in printable_settings: # Set value width to the available terminal space, or the min width width = tty_width - len(setting.key) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = (setting.value[:width] + '...' if len(setting.value) > width else setting.value) print('{}: {}'.format(setting.key, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['KEY', 'VALUE']) for setting in printable_settings: writer.writerow([setting.key, setting.value]) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': settings_snapshot = { 'head': head, 'settings': {setting.key: setting.value for setting in printable_settings} } if args.format == 'json': print(json.dumps(settings_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(settings_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def do_state(args): """Runs the batch list or batch show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': response = rest_client.list_state(args.subtree, args.head) leaves = response['data'] head = response['head'] keys = ('address', 'size', 'data') headers = tuple(k.upper() for k in keys) def parse_leaf_row(leaf, decode=True): decoded = b64decode(leaf['data']) return ( leaf['address'], len(decoded), str(decoded) if decode else leaf['data']) if args.format == 'default': fmt.print_terminal_table(headers, leaves, parse_leaf_row) print('HEAD BLOCK: "{}"'.format(head)) elif args.format == 'csv': fmt.print_csv(headers, leaves, parse_leaf_row) print('(data for head block: "{}")'.format(head)) elif args.format == 'json' or args.format == 'yaml': state_data = { 'head': head, 'data': [{k: d for k, d in zip(keys, parse_leaf_row(l, False))} for l in leaves]} if args.format == 'yaml': fmt.print_yaml(state_data) elif args.format == 'json': fmt.print_json(state_data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': output = rest_client.get_leaf(args.address, args.head) if output is not None: print('DATA: "{}"'.format(b64decode(output['data']))) print('HEAD: "{}"'.format(output['head'])) else: raise CliException('No data available at {}'.format(args.address))
def do_peer_list(args): rest_client = RestClient(base_url=args.url) peers = sorted(rest_client.list_peers()) if args.format == 'csv' or args.format == 'default': print(','.join(peers)) elif args.format == 'json': fmt.print_json(peers) elif args.format == 'yaml': fmt.print_yaml(peers)
def _do_identity_role_create(args): """Executes the 'role create' subcommand. Given a key file, a role name, and a policy name it generates a batch of sawtooth_identity transactions in a BatchList instance. The BatchList is either stored to a file or submitted to a validator, depending on the supplied CLI arguments. """ signer = _read_signer(args.key) txns = [_create_role_txn(signer, args.name, args.policy)] batch = _create_batch(signer, txns) batch_list = BatchList(batches=[batch]) if args.output is not None: try: with open(args.output, 'wb') as batch_file: batch_file.write(batch_list.SerializeToString()) except IOError as e: raise CliException( 'Unable to write to batch file: {}'.format(str(e))) elif args.url is not None: rest_client = RestClient(args.url) rest_client.send_batches(batch_list) if args.wait and args.wait > 0: batch_id = batch.header_signature wait_time = 0 start_time = time.time() while wait_time < args.wait: statuses = rest_client.get_statuses( [batch_id], args.wait - int(wait_time)) wait_time = time.time() - start_time if statuses[0]['status'] == 'COMMITTED': print( 'Role committed in {:.6} sec'.format(wait_time)) return # Wait a moment so as not to hammer the Rest Api time.sleep(0.2) print('Wait timed out! Role was not committed...') print('{:128.128} {}'.format( batch_id, statuses[0]['status'])) exit(1) else: raise AssertionError('No target for create set.')
def _do_identity_role_list(args): """Lists the current on-chain configuration values. """ rest_client = RestClient(args.url) state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _ROLE_PREFIX) head = state['head'] state_values = state['data'] printable_roles = [] for state_value in state_values: role_list = RoleList() decoded = b64decode(state_value['data']) role_list.ParseFromString(decoded) for role in role_list.roles: printable_roles.append(role) printable_roles.sort(key=lambda r: r.name) if args.format == 'default': tty_width = tty.width() for role in printable_roles: # Set value width to the available terminal space, or the min width width = tty_width - len(role.name) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = (role.policy_name[:width] + '...' if len(role.policy_name) > width else role.policy_name) print('{}: {}'.format(role.name, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['KEY', 'VALUE']) for role in printable_roles: writer.writerow([role.name, role.policy_name]) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': roles_snapshot = { 'head': head, 'roles': {role.name: role.policy_name for role in printable_roles} } if args.format == 'json': print(json.dumps(roles_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(roles_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def _do_identity_role_list(args): """Lists the current on-chain configuration values. """ rest_client = RestClient(args.url) state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _ROLE_PREFIX) head = state['head'] state_values = state['data'] printable_roles = [] for state_value in state_values: role_list = RoleList() decoded = b64decode(state_value['data']) role_list.ParseFromString(decoded) for role in role_list.roles: printable_roles.append(role) printable_roles.sort(key=lambda r: r.name) if args.format == 'default': tty_width = tty.width() for role in printable_roles: # Set value width to the available terminal space, or the min width width = tty_width - len(role.name) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = (role.policy_name[:width] + '...' if len(role.policy_name) > width else role.policy_name) print('{}: {}'.format(role.name, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['KEY', 'VALUE']) for role in printable_roles: writer.writerow([role.name, role.policy_name]) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': roles_snapshot = { 'head': head, 'roles': {role.name: role.policy_name for role in printable_roles} } if args.format == 'json': print(json.dumps(roles_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(roles_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def do_submit(args): with open(args.filename, mode='rb') as fd: batches = batch_pb2.BatchList() batches.ParseFromString(fd.read()) rest_client = RestClient(args.url) start = time.time() for batch_list in _split_batch_list(args, batches): rest_client.send_batches(batch_list) stop = time.time() print("batches: {} batch/sec: {}".format( str(len(batches.batches)), len(batches.batches) / (stop - start)))
def _do_identity_role_create(args): """Executes the 'role create' subcommand. Given a key file, a role name, and a policy name it generates a batch of sawtooth_identity transactions in a BatchList instance. The BatchList is either stored to a file or submitted to a validator, depending on the supplied CLI arguments. """ public_key, signing_key = _read_signing_keys(args.key) txns = [_create_role_txn(public_key, signing_key, args.name, args.policy)] batch = _create_batch(public_key, signing_key, txns) batch_list = BatchList(batches=[batch]) if args.output is not None: try: with open(args.output, 'wb') as batch_file: batch_file.write(batch_list.SerializeToString()) except IOError as e: raise CliException('Unable to write to batch file: {}'.format( str(e))) elif args.url is not None: rest_client = RestClient(args.url) rest_client.send_batches(batch_list) if args.wait and args.wait > 0: batch_id = batch.header_signature wait_time = 0 start_time = time.time() while wait_time < args.wait: statuses = rest_client.get_statuses([batch_id], args.wait - int(wait_time)) wait_time = time.time() - start_time if statuses[0]['status'] == 'COMMITTED': print('Role committed in {:.6} sec'.format(wait_time)) return # Wait a moment so as not to hammer the Rest Api time.sleep(0.2) print('Wait timed out! Role was not committed...') print('{:128.128} {}'.format(batch_id, statuses[0]['status'])) exit(1) else: raise AssertionError('No target for create set.')
def make_rest_apis(urls, users): clients = [] for i, url in enumerate(urls): try: user = users[i] except IndexError: user = '' clients.append(RestClient(url, user)) return clients
def do_batch_submit(args): try: with open(args.filename, mode='rb') as fd: batches = batch_pb2.BatchList() batches.ParseFromString(fd.read()) except IOError as e: raise CliException(e) rest_client = RestClient(args.url, args.user) start = time.time() for batch_list in _split_batch_list(args, batches): rest_client.send_batches(batch_list) stop = time.time() print('batches: {}, batch/sec: {}'.format( str(len(batches.batches)), len(batches.batches) / (stop - start))) if args.wait and args.wait > 0: batch_ids = [b.header_signature for b in batches.batches] wait_time = 0 start_time = time.time() while wait_time < args.wait: statuses = rest_client.get_statuses( batch_ids, args.wait - int(wait_time)) wait_time = time.time() - start_time if all(s.status == 'COMMITTED' for s in statuses): print('All batches committed in {:.6} sec'.format(wait_time)) return # Wait a moment so as not to hammer the Rest Api time.sleep(0.2) print('Wait timed out! Some batches have not yet been committed...') for batch_id, status in statuses.items(): print('{:128.128} {:10.10}'.format(batch_id, status)) exit(1)
def do_batch_submit(args): try: with open(args.filename, mode='rb') as fd: batches = batch_pb2.BatchList() batches.ParseFromString(fd.read()) except IOError as e: raise CliException(e) rest_client = RestClient(args.url, args.user) start = time.time() for batch_list in _split_batch_list(args, batches): rest_client.send_batches(batch_list) stop = time.time() print('batches: {}, batch/sec: {}'.format( str(len(batches.batches)), len(batches.batches) / (stop - start))) if args.wait and args.wait > 0: batch_ids = [b.header_signature for b in batches.batches] wait_time = 0 start_time = time.time() while wait_time < args.wait: statuses = rest_client.get_statuses( batch_ids, args.wait - int(wait_time)) wait_time = time.time() - start_time if all(s['status'] == 'COMMITTED' for s in statuses): print('All batches committed in {:.6} sec'.format(wait_time)) return # Wait a moment so as not to send another request immediately time.sleep(0.2) print('Wait timed out! Some batches have not yet been committed...') for batch_id, status in statuses.items(): print('{:128.128} {:10.10}'.format(batch_id, status)) exit(1)
def do_batch_show(args): rest_client = RestClient(args.url, args.user) output = rest_client.get_batch(args.batch_id) if args.key: if args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'key "{}" not found in batch or header'.format(args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_batch_show(args): rest_client = RestClient(args.url, args.user) output = rest_client.get_batch(args.batch_id) if args.key: if args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException('key "{}" not found in batch or header'.format( args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_batch_status(args): """Runs the batch-status command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) batch_ids = args.batch_ids.split(',') if args.wait and args.wait > 0: statuses = rest_client.get_statuses(batch_ids, args.wait) else: statuses = rest_client.get_statuses(batch_ids) if args.format == 'yaml': fmt.print_yaml(statuses) elif args.format == 'json': fmt.print_json(statuses) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_batch_status(args): """Runs the batch-status command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) batch_ids = args.batch_ids.split(',') if args.wait and args.wait > 0: statuses = rest_client.get_statuses(batch_ids, args.wait) else: statuses = rest_client.get_statuses(batch_ids) if args.format == 'yaml': fmt.print_yaml(statuses) elif args.format == 'json': fmt.print_json(statuses) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_dag(args): """Runs the head list or block show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': heads = sorted(rest_client.list_dag()) if args.format == 'csv' or args.format == 'default': print(','.join(heads)) elif args.format == 'json': fmt.print_json(heads) elif args.format == 'yaml': fmt.print_yaml(heads) if args.subcommand == 'show': output = rest_client.get_dag(args.head_id) if args.key: if args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'key "{}" not found in block or header'.format(args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
def _do_config_proposal_vote(args): """Executes the 'proposal vote' subcommand. Given a key file, a proposal id and a vote value, it generates a batch of sawtooth_settings transactions in a BatchList instance. The BatchList is file or submitted to a validator. """ public_key, signing_key = _read_signing_keys(args.key) rest_client = RestClient(args.url) proposals = _get_proposals(rest_client) proposal = None for candidate in proposals.candidates: if candidate.proposal_id == args.proposal_id: proposal = candidate break if proposal is None: raise CliException('No proposal exists with the given id') for vote_record in proposal.votes: if vote_record.public_key == public_key: raise CliException( 'A vote has already been recorded with this signing key') txn = _create_vote_txn( public_key, signing_key, args.proposal_id, proposal.proposal.setting, args.vote_value) batch = _create_batch(public_key, signing_key, [txn]) batch_list = BatchList(batches=[batch]) rest_client.send_batches(batch_list)
def _do_config_proposal_list(args): """Executes the 'proposal list' subcommand. Given a url, optional filters on prefix and public key, this command lists the current pending proposals for settings changes. """ def _accept(candidate, public_key, prefix): # Check to see if the first public key matches the given public key # (if it is not None). This public key belongs to the user that # created it. has_pub_key = (not public_key or candidate.votes[0].public_key == public_key) has_prefix = candidate.proposal.setting.startswith(prefix) return has_prefix and has_pub_key candidates_payload = _get_proposals(RestClient(args.url)) candidates = [ c for c in candidates_payload.candidates if _accept(c, args.public_key, args.filter) ] if args.format == 'default': for candidate in candidates: print('{}: {} => {}'.format( candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value)) elif args.format == 'csv': writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['PROPOSAL_ID', 'KEY', 'VALUE']) for candidate in candidates: writer.writerow([ candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value]) elif args.format == 'json' or args.format == 'yaml': candidates_snapshot = \ {c.proposal_id: {c.proposal.setting: c.proposal.value} for c in candidates} if args.format == 'json': print(json.dumps(candidates_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(candidates_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def _do_identity_policy_list(args): rest_client = RestClient(args.url) state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _POLICY_PREFIX) head = state['head'] state_values = state['data'] printable_policies = [] for state_value in state_values: policies_list = PolicyList() decoded = b64decode(state_value['data']) policies_list.ParseFromString(decoded) for policy in policies_list.policies: printable_policies.append(policy) printable_policies.sort(key=lambda p: p.name) if args.format == 'default': tty_width = tty.width() for policy in printable_policies: # Set value width to the available terminal space, or the min width width = tty_width - len(policy.name) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = "Entries:\n" for entry in policy.entries: entry_string = (" " * 4) + Policy.Type.Name(entry.type) + " " \ + entry.key value += (entry_string[:width] + '...' if len(entry_string) > width else entry_string) + "\n" print('{}: \n {}'.format(policy.name, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['POLICY NAME', 'ENTRIES']) for policy in printable_policies: output = [policy.name] for entry in policy.entries: output.append( Policy.Type.Name(entry.type) + " " + entry.key) writer.writerow(output) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': output = {} for policy in printable_policies: value = "Entries: " for entry in policy.entries: entry_string = Policy.Type.Name(entry.type) + " " \ + entry.key value += entry_string + " " output[policy.name] = value policies_snapshot = { 'head': head, 'policies': output } if args.format == 'json': print(json.dumps(policies_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(policies_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def setUpClass(cls): url = 'rest-api:8080' wait_for_rest_apis([url]) http = 'http://' + url cls.client = RestClient(http) cls.client.url = http
def do_block(args): """Runs the block list or block show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': block_generator = rest_client.list_blocks() blocks = [] left = args.count for block in block_generator: blocks.append(block) left -= 1 if left <= 0: break keys = ('num', 'block_id', 'batches', 'txns', 'signer') headers = tuple(k.upper() if k != 'batches' else 'BATS' for k in keys) def parse_block_row(block): batches = block.get('batches', []) txns = [t for b in batches for t in b['transactions']] return (block['header'].get('block_num', 0), block['header_signature'], len(batches), len(txns), block['header']['signer_public_key']) if args.format == 'default': fmt.print_terminal_table(headers, blocks, parse_block_row) elif args.format == 'csv': fmt.print_csv(headers, blocks, parse_block_row) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, parse_block_row(b))} for b in blocks] if args.format == 'yaml': fmt.print_yaml(data) elif args.format == 'json': fmt.print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': output = rest_client.get_block(args.block_id) if args.key: if args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'key "{}" not found in block or header'.format(args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_state(args): """Runs the batch list or batch show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url) def print_json(data): print( json.dumps(data, indent=2, separators=(',', ': '), sort_keys=True)) def print_yaml(data): print(yaml.dump(data, default_flow_style=False)[0:-1]) if args.subcommand == 'list': response = rest_client.list_state(args.subtree, args.head) leaves = response['data'] head = response['head'] keys = ('address', 'size', 'data') headers = (k.upper() for k in keys) def get_leaf_data(leaf, decode=True): decoded = b64decode(leaf['data']) return (leaf['address'], len(decoded), str(decoded) if decode else leaf['data']) if args.format == 'default': # Set column widths based on window and data size window_width = tty.width() try: addr_width = len(leaves[0]['address']) data_width = len(str(b64decode(leaves[0]['data']))) except IndexError: # if no data was returned, use short default widths addr_width = 30 data_width = 15 if sys.stdout.isatty(): adjusted = int(window_width) - addr_width - 11 adjusted = 6 if adjusted < 6 else adjusted else: adjusted = data_width fmt_string = '{{:{a}.{a}}} {{:<4}} {{:{j}.{j}}}'\ .format(a=addr_width, j=adjusted) # Print data in rows and columns print(fmt_string.format(*headers)) for leaf in leaves: print( fmt_string.format(*get_leaf_data(leaf)) + ('...' if adjusted < data_width and data_width else '')) print('HEAD BLOCK: "{}"'.format(head)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout) writer.writerow(headers) for leaf in leaves: writer.writerow(get_leaf_data(leaf)) except csv.Error as e: raise CliException('Error writing CSV: {}'.format(e)) print('(data for head block: "{}")'.format(head)) elif args.format == 'json' or args.format == 'yaml': state_data = { 'head': head, 'data': [{k: d for k, d in zip(keys, get_leaf_data(l, False))} for l in leaves] } if args.format == 'yaml': print_yaml(state_data) elif args.format == 'json': print_json(state_data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': leaf = rest_client.get_leaf(args.address, args.head) if leaf is not None: print('DATA: "{}"'.format(b64decode(leaf['data']))) print('HEAD: "{}"'.format(leaf['head'])) else: raise CliException('No data available at {}'.format(args.address))
def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url))
def do_state(args): rest_client = RestClient(args.url) def print_json(data): print( json.dumps(data, indent=2, separators=(',', ': '), sort_keys=True)) def print_yaml(data): print(yaml.dump(data, default_flow_style=False)[0:-1]) if args.subcommand == 'list': response = rest_client.list_state(args.subtree, args.head) leaves = response['data'] head = response['head'] keys = ('address', 'size', 'data') headers = (k.upper() for k in keys) max_data_width = 15 format_string = '{{:{addr}.{addr}}} {{:<4}} {{!s:.{data}}}'.format( addr=len(leaves[0]['address']) if len(leaves) > 0 else 30, data=max_data_width) def get_leaf_data(leaf, use_decoded=True): data = leaf['data'] decoded_data = b64decode(data) return (leaf['address'], len(decoded_data), decoded_data if use_decoded else data) if args.format == 'default': print(format_string.format(*headers)) for leaf in leaves: print_string = format_string.format(*get_leaf_data(leaf)) if len(str(leaf['data'])) > max_data_width: print_string += '...' print(print_string) print('HEAD BLOCK: "{}"'.format(head)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout) writer.writerow(headers) for leaf in leaves: writer.writerow(get_leaf_data(leaf)) except csv.Error: raise CliException('Error writing CSV.') print('(data for head block: "{}")'.format(head)) elif args.format == 'json' or args.format == 'yaml': state_data = { 'head': head, 'data': list( map(lambda b: dict(zip(keys, get_leaf_data(b, False))), leaves)) } if args.format == 'json': print_json(state_data) else: print_yaml(state_data) else: raise CliException('Unknown format: {}'.format(args.format)) if args.subcommand == 'show': leaf = rest_client.get_leaf(args.address, args.head) print('DATA: "{}"'.format(b64decode(leaf['data']))) print('HEAD: "{}"'.format(leaf['head']))
class MarketplaceClient(object): def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) def create_account(self, key, label, description): batches, signature = transaction_creation.create_account( txn_key=key, batch_key=BATCH_KEY, label=label, description=description) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_asset(self, key, name, description, rules): batches, signature = transaction_creation.create_asset( txn_key=key, batch_key=BATCH_KEY, name=name, description=description, rules=rules) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_holding(self, key, identifier, label, description, asset, quantity): batches, signature = transaction_creation.create_holding( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, label=label, description=description, asset=asset, quantity=quantity) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_offer(self, key, identifier, label, description, source, target, rules): batches, signature = transaction_creation.create_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, label=label, description=description, source=source, target=target, rules=rules) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def accept_offer(self, key, identifier, receiver, offerer, count): batches, signature = transaction_creation.accept_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, offerer=offerer, receiver=receiver, count=count) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def close_offer(self, key, identifier): batches, signature = transaction_creation.close_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10)
def __init__(self, url, key): if url is None: url = REST_ENDPOINT self._client = RestClient(base_url=url) self._key = key
def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) self._family_name = 'certificate_registry' self._family_version = '0.1' self._namespace = hashlib.sha256( self._family_name.encode('utf-8')).hexdigest()[:6]
def do_block(args): subcommands = ['list', 'show'] if args.subcommand not in subcommands: print('Unknown sub-command, expecting one of {0}'.format( subcommands)) return rest_client = RestClient(args.url) def print_json(data): print(json.dumps( data, indent=2, separators=(',', ': '), sort_keys=True)) def print_yaml(data): print(yaml.dump(data, default_flow_style=False)[0:-1]) if args.subcommand == 'list': blocks = rest_client.list_blocks() keys = ('num', 'block_id', 'batches', 'txns', 'signer') headers = (k.upper() for k in keys) def get_block_data(block): batches = block.get('batches', []) txn_count = reduce( lambda t, b: t + len(b.get('transactions', [])), batches, 0) return ( block['header'].get('block_num', 0), block['header_signature'], len(batches), txn_count, block['header']['signer_pubkey'] ) if args.format == 'default': print('{:<3} {:88.88} {:<7} {:<4} {:20.20}'.format(*headers)) for block in blocks: print('{:<3} {:88.88} {:<7} {:<4} {:17.17}...'.format( *get_block_data(block))) elif args.format == 'csv': try: writer = csv.writer(sys.stdout) writer.writerow(headers) for block in blocks: writer.writerow(get_block_data(block)) except csv.Error: raise CliException('Error writing CSV.') elif args.format == 'json' or args.format == 'yaml': block_data = list(map( lambda b: dict(zip(keys, get_block_data(b))), blocks )) if args.format == 'json': print_json(block_data) else: print_yaml(block_data) else: raise CliException('unknown format: {}'.format(args.format)) elif args.subcommand == 'show': block = rest_client.get_block(args.block_id) if args.key: if args.key in block: print(block[args.key]) elif args.key in block['header']: print(block['header'][args.key]) else: raise CliException( 'key "{}" not found in block or header'.format(args.key)) else: if args.format == 'yaml': print_yaml(block) elif args.format == 'json': print_json(block) else: raise CliException('unknown format: {}'.format(args.format))
def _do_identity_policy_list(args): rest_client = RestClient(args.url) state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _POLICY_PREFIX) head = state['head'] state_values = state['data'] printable_policies = [] for state_value in state_values: policies_list = PolicyList() decoded = b64decode(state_value['data']) policies_list.ParseFromString(decoded) for policy in policies_list.policies: printable_policies.append(policy) printable_policies.sort(key=lambda p: p.name) if args.format == 'default': tty_width = tty.width() for policy in printable_policies: # Set value width to the available terminal space, or the min width width = tty_width - len(policy.name) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = "Entries:\n" for entry in policy.entries: entry_string = (" " * 4) + Policy.EntryType.Name(entry.type) \ + " " + entry.key value += (entry_string[:width] + '...' if len(entry_string) > width else entry_string) + "\n" print('{}: \n {}'.format(policy.name, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['POLICY NAME', 'ENTRIES']) for policy in printable_policies: output = [policy.name] for entry in policy.entries: output.append( Policy.EntryType.Name(entry.type) + " " + entry.key) writer.writerow(output) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': output = {} for policy in printable_policies: value = "Entries: " for entry in policy.entries: entry_string = Policy.EntryType.Name(entry.type) + " " \ + entry.key value += entry_string + " " output[policy.name] = value policies_snapshot = { 'head': head, 'policies': output } if args.format == 'json': print(json.dumps(policies_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(policies_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
class SimpleSupplyClient(object): def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) def create_agent(self, key, name, timestamp): batch = transaction_creation.make_create_agent_transaction( transaction_signer=key, batch_signer=BATCH_KEY, name=name, timestamp=timestamp) batch_id = batch.header_signature batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=10) def create_record(self, key, latitude, longitude, record_id, timestamp): batch = transaction_creation.make_create_record_transaction( transaction_signer=key, batch_signer=BATCH_KEY, latitude=latitude, longitude=longitude, record_id=record_id, timestamp=timestamp) batch_id = batch.header_signature batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=10) def transfer_record(self, key, receiving_agent, record_id, timestamp): batch = transaction_creation.make_transfer_record_transaction( transaction_signer=key, batch_signer=BATCH_KEY, receiving_agent=receiving_agent, record_id=record_id, timestamp=timestamp) batch_id = batch.header_signature batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=10) def update_record(self, key, latitude, longitude, record_id, timestamp): batch = transaction_creation.make_update_record_transaction( transaction_signer=key, batch_signer=BATCH_KEY, latitude=latitude, longitude=longitude, record_id=record_id, timestamp=timestamp) batch_id = batch.header_signature batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=10)
class MarketplaceClient(object): def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) def create_account(self, key, label, description): batches, signature = transaction_creation.create_account( txn_key=key, batch_key=BATCH_KEY, label=label, description=description) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_asset(self, key, name, description, rules): batches, signature = transaction_creation.create_asset( txn_key=key, batch_key=BATCH_KEY, name=name, description=description, rules=rules) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_holding(self, key, identifier, label, description, asset, quantity): batches, signature = transaction_creation.create_holding( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, label=label, description=description, asset=asset, quantity=quantity) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_offer(self, key, identifier, label, description, source, target, rules): batches, signature = transaction_creation.create_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, label=label, description=description, source=source, target=target, rules=rules) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def accept_offer(self, key, identifier, receiver, offerer, count): batches, signature = transaction_creation.accept_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier, offerer=offerer, receiver=receiver, count=count) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def close_offer(self, key, identifier): batches, signature = transaction_creation.close_offer( txn_key=key, batch_key=BATCH_KEY, identifier=identifier) batch_list = batch_pb2.BatchList(batches=batches) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10)
def do_transaction(args): """Runs the transaction list or show command, printing to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': transactions = rest_client.list_transactions() keys = ('transaction_id', 'family', 'version', 'size', 'payload') headers = tuple(k.upper() if k != 'version' else 'VERS' for k in keys) def parse_txn_row(transaction, decode=True): decoded = b64decode(transaction['payload']) return ( transaction['header_signature'], transaction['header']['family_name'], transaction['header']['family_version'], len(decoded), str(decoded) if decode else transaction['payload']) if args.format == 'default': fmt.print_terminal_table(headers, transactions, parse_txn_row) elif args.format == 'csv': fmt.print_csv(headers, transactions, parse_txn_row) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, parse_txn_row(b, False))} for b in transactions] if args.format == 'yaml': fmt.print_yaml(data) elif args.format == 'json': fmt.print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': output = rest_client.get_transaction(args.transaction_id) if args.key: if args.key == 'payload': output = b64decode(output['payload']) elif args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'Key "{}" not found in transaction or header'.format( args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
def do_batch(args): """Runs the batch list or batch show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url) def print_json(data): print( json.dumps(data, indent=2, separators=(',', ': '), sort_keys=True)) def print_yaml(data): print(yaml.dump(data, default_flow_style=False)[0:-1]) if args.subcommand == 'list': batches = rest_client.list_batches() keys = ('batch_id', 'txns', 'signer') headers = (k.upper() for k in keys) def get_data(batch): return (batch['header_signature'], len(batch.get('transactions', [])), batch['header']['signer_pubkey']) if args.format == 'default': # Set column widths based on window and data size window_width = tty.width() try: id_width = len(batches[0]['header_signature']) sign_width = len(batches[0]['header']['signer_pubkey']) except IndexError: # if no data was returned, use short default widths id_width = 30 sign_width = 15 if sys.stdout.isatty(): adjusted = int(window_width) - id_width - 11 adjusted = 6 if adjusted < 6 else adjusted else: adjusted = sign_width fmt_string = '{{:{i}.{i}}} {{:<4}} {{:{a}.{a}}}'\ .format(i=id_width, a=adjusted) # Print data in rows and columns print(fmt_string.format(*headers)) for batch in batches: print( fmt_string.format(*get_data(batch)) + ('...' if adjusted < sign_width and sign_width else '')) elif args.format == 'csv': try: writer = csv.writer(sys.stdout) writer.writerow(headers) for batch in batches: writer.writerow(get_data(batch)) except csv.Error as e: raise CliException('Error writing CSV: {}'.format(e)) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, get_data(b))} for b in batches] if args.format == 'yaml': print_yaml(data) elif args.format == 'json': print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': batch = rest_client.get_batch(args.batch_id) if args.key: if args.key in batch: print(batch[args.key]) elif args.key in batch['header']: print(batch['header'][args.key]) else: raise CliException( 'key "{}" not found in batch or header'.format(args.key)) else: if args.format == 'yaml': print_yaml(batch) elif args.format == 'json': print_json(batch) else: raise AssertionError('Missing handler: {}'.format(args.format))
class ConsensourceTestClient(): """Client application for Consensource used for testing. This class defines methods for each transaction and data type covered by the integration test suite. Args: url (str): URL of the Sawtooth REST API. Attributes: _client (RestClient): Defines functions for interfacing with the Sawtooth REST API. _family_name (str): Name of the application. This should match the family name in the transaction processor's metadata. _family_version (str): Version of the application. This should match the family version in the transaction processor's metadata. _namespace (str): First 6 chars of the family name """ def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) self._family_name = 'certificate_registry' self._family_version = '0.1' self._namespace = hashlib.sha256( self._family_name.encode('utf-8')).hexdigest()[:6] def create_agent(self, signer, name, timestamp): """Creates and submits a create agent transaction. Args: signer (Signer): Transaction and batch signer. name (str): Name of the agent. timestamp(int): Unix timestamp at which the transaction is being submitted. Returns: list of dict: Dicts with 'id' and 'status' properties. """ agent_address = self._make_agent_address( signer.get_public_key().as_hex()) payload = payload_pb2.CertificateRegistryPayload( action=payload_pb2.CertificateRegistryPayload.CREATE_AGENT, create_agent=payload_pb2.CreateAgentAction(name=name, timestamp=timestamp)) batch = self._make_batch(payload=payload, inputs=[agent_address], outputs=[agent_address], signer=signer) return self._send_batch(batch) def fetch_agent(self, public_key): """Fetches an agent resource from state. Args: public_key (str): Public key that identifies the agent. Returns: agent_pb2.Agent: Protobuf message describing the agent. """ agent_address = self._make_agent_address(public_key) state = self._client.list_state(subtree=agent_address) if state: container = agent_pb2.AgentContainer() container.ParseFromString(b64decode(state['data'][0]['data'])) for agent in container.entries: if agent.public_key == public_key: return agent return None def _make_agent_address(self, public_key): """Addressing method for agents. """ return self._namespace + '00' + '00' + hashlib.sha256( public_key.encode('utf-8')).hexdigest()[:60] def _make_batch(self, payload, inputs, outputs, signer): """Creates and signs a batch. """ signer_public_key = signer.get_public_key().as_hex() payload_bytes = payload.SerializeToString() txn_header = transaction_pb2.TransactionHeader( family_name=self._family_name, family_version=self._family_version, inputs=inputs, outputs=outputs, signer_public_key=signer_public_key, batcher_public_key=signer_public_key, payload_sha512=hashlib.sha512(payload_bytes).hexdigest()) txn_header_bytes = txn_header.SerializeToString() txn = transaction_pb2.Transaction( header=txn_header_bytes, header_signature=signer.sign(txn_header_bytes), payload=payload_bytes) batch_header = batch_pb2.BatchHeader( signer_public_key=signer_public_key, transaction_ids=[txn.header_signature]) batch_header_bytes = batch_header.SerializeToString() batch = batch_pb2.Batch( header=batch_header_bytes, header_signature=signer.sign(batch_header_bytes), transactions=[txn]) return batch def _send_batch(self, batch): """Submits a batch to the validator. After submission, the client will query the REST API again to retrieve the commit status of the batch. """ batch_id = batch.header_signature batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=10)
def __init__(self, url, key): self._client = RestClient(base_url=url) self._key = key
def do_transaction(args): """Runs the transaction list or show command, printing to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': transactions = rest_client.list_transactions() keys = ('transaction_id', 'family', 'version', 'size', 'payload') headers = tuple(k.upper() if k != 'version' else 'VERS' for k in keys) def parse_txn_row(transaction, decode=True): decoded = b64decode(transaction['payload']) return (transaction['header_signature'], transaction['header']['family_name'], transaction['header']['family_version'], len(decoded), str(decoded) if decode else transaction['payload']) if args.format == 'default': fmt.print_terminal_table(headers, transactions, parse_txn_row) elif args.format == 'csv': fmt.print_csv(headers, transactions, parse_txn_row) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, parse_txn_row(b, False))} for b in transactions] if args.format == 'yaml': fmt.print_yaml(data) elif args.format == 'json': fmt.print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': output = rest_client.get_transaction(args.transaction_id) if args.key: if args.key == 'payload': output = b64decode(output['payload']) elif args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'Key "{}" not found in transaction or header'.format( args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))
class HealthCareClient(object): def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url)) def create_doctor(self, txn_signer, batch_signer, name, surname): # doctor = payload_pb2.CreateDoctor( # public_key=txn_signer.get_public_key().as_hex(), # name=name, # surname=surname) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.CREATE_DOCTOR, # create_doctor=doctor) # # doctor_hex = helper.make_doctor_address(doctor_pkey=txn_signer.get_public_key().as_hex()) # # batch, signature = self._create_txn_and_batch(txn_signer, batch_signer, [doctor_hex], [doctor_hex], payload) batch, batch_id = transaction.create_doctor(txn_signer=txn_signer, batch_signer=batch_signer, name=name, surname=surname) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=40) def create_patient(self, txn_signer, batch_signer, name, surname): # patient = payload_pb2.CreatePatient( # public_key=txn_key.get_public_key().as_hex(), # name=name, # surname=surname) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.CREATE_PATIENT, # create_patient=patient) # # patient_hex = helper.make_patient_address(patient_pkey=txn_key.get_public_key().as_hex()) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [patient_hex], [patient_hex], payload) batch, batch_id = transaction.create_patient(txn_signer=txn_signer, batch_signer=batch_signer, name=name, surname=surname) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=40) def create_clinic(self, txn_signer, batch_signer, name): # clinic = payload_pb2.CreateClinic( # public_key=txn_signer.get_public_key().as_hex(), # name=name) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.CREATE_CLINIC, # create_clinic=clinic) # # clinic_hex = helper.make_clinic_address(clinic_pkey=txn_signer.get_public_key().as_hex()) # # batch, batch_id = self._create_txn_and_batch(txn_signer, BATCH_KEY, [clinic_hex], [clinic_hex], payload) batch, batch_id = transaction.create_clinic(txn_signer=txn_signer, batch_signer=batch_signer, name=name) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=40) def create_claim(self, txn_signer, batch_signer, claim_id, patient_pkey): # clinic_pkey = txn_key.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # # claim = payload_pb2.CreateClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # patient_pkey=patient_pkey) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.CREATE_CLAIM, # create_claim=claim) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, clinic_hex], [claim_hex], payload) # # batch_list = batch_pb2.BatchList(batches=[batch]) batch, batch_id = transaction.register_claim(txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, patient_pkey=patient_pkey) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=40) # def create_claim(self, txn_key, claim_id, patient_pkey): # clinic_pkey = txn_key.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # # claim = payload_pb2.CreateClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # patient_pkey=patient_pkey) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.CREATE_CLAIM, # create_claim=claim) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, clinic_hex], [claim_hex], payload) # # batch_list = batch_pb2.BatchList(batches=[batch]) # # self._client.send_batches(batch_list) # return self._client.get_statuses([signature], wait=40) def assign_doctor(self, txn_signer, batch_signer, claim_id, doctor_pkey): # clinic_pkey = txn_signer.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # assign = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Doctor: {}, assigned to claim: {}".format(doctor_pkey, claim_hex), # event_time=current_times_str) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.ASSIGN_DOCTOR, # assign_doctor=assign) # # batch, signature = self._create_txn_and_batch(txn_signer, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) current_times_str = str(time.time()) # clinic_signer = request.app.config.SIGNER # .get_public_key().as_hex() batch, batch_id = transaction.assign_doctor( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Doctor pkey: {}, assigned to claim: {}".format( doctor_pkey, claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def first_visit(self, txn_signer, batch_signer, claim_id, doctor_pkey): # clinic_pkey = txn_key.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # first_visit = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Doctor: {}, completed first visit for claim: {}, \ # need to pass procedures and eat pills".format(doctor_pkey, claim_hex), # event_time=current_times_str # ) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.FIRST_VISIT, # first_visit=first_visit) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) current_times_str = str(time.time()) batch, batch_id = transaction.first_visit( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Doctor: {}, completed first visit for claim: {}, \ need to pass procedures and eat pills".format( doctor_pkey, claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def pass_tests(self, txn_signer, batch_signer, claim_id): current_times_str = str(time.time()) # clinic_pkey = txn_signer.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # # # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # tests = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Pass tests in scope of claim: {}".format(claim_hex), # event_time=current_times_str # ) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.PASS_TESTS, # pass_tests=tests) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) batch, batch_id = transaction.pass_tests( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Pass tests in scope of claim: {}".format(claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def attend_procedures(self, txn_signer, batch_signer, claim_id): # clinic_pkey = txn_key.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # procedures = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Complete procedure in scope of claim: {}".format(claim_hex), # event_time=current_times_str # ) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.ATTEND_PROCEDURES, # attend_procedures=procedures) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) current_times_str = str(time.time()) batch, batch_id = transaction.attend_procedures( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Complete procedure in scope of claim: {}".format( claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def eat_pills(self, txn_signer, batch_signer, claim_id): # clinic_pkey = txn_signer.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # pills = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Eat pills in scope of claim: {}".format(claim_hex), # event_time=current_times_str # ) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.EAT_PILLS, # eat_pills=pills) # # batch, batch_id = self._create_txn_and_batch(txn_signer, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) current_times_str = str(time.time()) batch, batch_id = transaction.eat_pills( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Eat pills in scope of claim: {}".format(claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def next_visit(self, txn_signer, batch_signer, claim_id, doctor_pkey): # clinic_pkey = txn_key.get_public_key().as_hex() # clinic_hex = helper.make_clinic_address(clinic_pkey=clinic_pkey) # claim_hex = helper.make_claim_address(claim_id=claim_id, clinic_pkey=clinic_pkey) # current_times_str = str(time.time()) # event_hex = helper.make_event_address(claim_id=claim_id, clinic_pkey=clinic_pkey, event_time=current_times_str) # # next_visit = payload_pb2.ActionOnClaim( # claim_id=claim_id, # clinic_pkey=clinic_pkey, # description="Doctor: {}, completed next visit for claim: {}".format(doctor_pkey, claim_hex), # event_time=current_times_str # ) # # payload = payload_pb2.TransactionPayload( # payload_type=payload_pb2.TransactionPayload.NEXT_VISIT, # next_visit=next_visit) # # batch, signature = self._create_txn_and_batch(txn_key, BATCH_KEY, [claim_hex, event_hex, clinic_hex], # [event_hex], payload) current_times_str = str(time.time()) batch, batch_id = transaction.next_visit( txn_signer=txn_signer, batch_signer=batch_signer, claim_id=claim_id, description="Doctor: {}, completed next visit for claim: {}". format(doctor_pkey, claim_id), event_time=current_times_str) batch_list = batch_pb2.BatchList(batches=[batch]) self._client.send_batches(batch_list) return self._client.get_statuses([batch_id], wait=80) def list_claims(self): claim_list_prefix = helper.make_claim_list_address() return self._client.list_state(subtree=claim_list_prefix) def list_doctors(self): doctor_list_prefix = helper.make_doctor_list_address() return self._client.list_state(subtree=doctor_list_prefix) def list_patients(self): patient_list_prefix = helper.make_patient_list_address() return self._client.list_state(subtree=patient_list_prefix) def list_clinics(self): clinic_list_prefix = helper.make_clinic_list_address() return self._client.list_state(subtree=clinic_list_prefix) def list_claim_details(self, claim_id, clinic_pkey): claim_details_prefix = helper.make_event_list_address( claim_id=claim_id, clinic_pkey=clinic_pkey) return self._client.list_state(subtree=claim_details_prefix) def _create_txn_and_batch(self, txn_key, batch_key, inputs, outputs, payload): txn_header_bytes, signature = self._transaction_header( txn_key, batch_key, inputs, outputs, payload) txn = transaction_pb2.Transaction(header=txn_header_bytes, header_signature=signature, payload=payload.SerializeToString()) transactions = [txn] batch_header_bytes, signature = self._batch_header( batch_key, transactions) batch = batch_pb2.Batch(header=batch_header_bytes, header_signature=signature, transactions=transactions) return batch, signature @staticmethod def _transaction_header(txn_key, batch_key, inputs, outputs, payload): txn_header_bytes = transaction_pb2.TransactionHeader( family_name=helper.TP_FAMILYNAME, family_version=helper.TP_VERSION, inputs=inputs, outputs=outputs, signer_public_key=txn_key.get_public_key().as_hex( ), # signer.get_public_key().as_hex(), # In this example, we're signing the batch with the same private key, # but the batch can be signed by another party, in which case, the # public key will need to be associated with that key. batcher_public_key=batch_key.get_public_key().as_hex( ), # signer.get_public_key().as_hex(), # In this example, there are no dependencies. This list should include # an previous transaction header signatures that must be applied for # this transaction to successfully commit. # For example, # dependencies=['540a6803971d1880ec73a96cb97815a95d374cbad5d865925e5aa0432fcf1931539afe10310c122c5eaae15df61236079abbf4f258889359c4d175516934484a'], dependencies=[], nonce=random.random().hex().encode(), payload_sha512=hashlib.sha512( payload.SerializeToString()).hexdigest()).SerializeToString() signature = txn_key.sign(txn_header_bytes) return txn_header_bytes, signature @staticmethod def _batch_header(batch_key, transactions): batch_header_bytes = batch_pb2.BatchHeader( signer_public_key=batch_key.get_public_key().as_hex(), transaction_ids=[txn.header_signature for txn in transactions]).SerializeToString() signature = batch_key.sign(batch_header_bytes) return batch_header_bytes, signature
def __init__(self, url): self._client = RestClient(base_url="http://{}".format(url))
class RbacClient(object): def __init__(self, url, key): if url is None: url = REST_ENDPOINT self._client = RestClient(base_url=url) self._key = key def return_state(self): items = [] for item in self._client.list_state(subtree=addresser.NS)["data"]: if addresser.address_is( item["address"]) == addresser.AddressSpace.USER: user_container = user_state_pb2.UserContainer() user_container.ParseFromString(b64decode(item["data"])) items.append((user_container, addresser.AddressSpace.USER)) return items def create_user(self, key, name, user_name, user_id, manager_id=None): batch_list, signature = create_user( txn_key=key, batch_key=self._key, name=name, user_name=user_name, user_id=user_id, metadata=uuid4().hex, manager_id=manager_id, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_role(self, key, role_name, role_id, metadata, admins, owners): batch_list, signature = role_transaction_creation.create_role( txn_key=key, batch_key=self._key, role_name=role_name, role_id=role_id, metadata=metadata, admins=admins, owners=owners, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_update_manager(self, key, proposal_id, user_id, new_manager_id, reason, metadata): batch_list, signature = manager_transaction_creation.propose_manager( txn_key=key, batch_key=self._key, proposal_id=proposal_id, user_id=user_id, new_manager_id=new_manager_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_update_manager(self, key, proposal_id, reason, user_id, manager_id): batch_list, signature = manager_transaction_creation.confirm_manager( txn_key=key, batch_key=self._key, proposal_id=proposal_id, reason=reason, user_id=user_id, manager_id=manager_id, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_update_manager(self, key, proposal_id, reason, user_id, manager_id): batch_list, signature = manager_transaction_creation.reject_manager( txn_key=key, batch_key=self._key, proposal_id=proposal_id, reason=reason, user_id=user_id, manager_id=manager_id, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_role_admins(self, key, proposal_id, role_id, user_id, reason, metadata): batch_list, signature = role_transaction_creation.propose_add_role_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_role_admins(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.confirm_add_role_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_role_admins(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.reject_add_role_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_role_owners(self, key, proposal_id, role_id, user_id, reason, metadata): batch_list, signature = role_transaction_creation.propose_add_role_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_role_owners(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.confirm_add_role_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_role_owners(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.reject_add_role_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_role_members(self, key, proposal_id, role_id, user_id, reason, metadata): batch_list, signature = role_transaction_creation.propose_add_role_members( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_role_members(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.confirm_add_role_members( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_role_members(self, key, proposal_id, role_id, user_id, reason): batch_list, signature = role_transaction_creation.reject_add_role_members( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_role_tasks(self, key, proposal_id, role_id, task_id, reason, metadata): batch_list, signature = role_transaction_creation.propose_add_role_tasks( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, task_id=task_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_role_tasks(self, key, proposal_id, role_id, task_id, reason): batch_list, signature = role_transaction_creation.confirm_add_role_tasks( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, task_id=task_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_role_tasks(self, key, proposal_id, role_id, task_id, reason): batch_list, signature = role_transaction_creation.reject_add_role_tasks( txn_key=key, batch_key=self._key, proposal_id=proposal_id, role_id=role_id, task_id=task_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def create_task(self, key, task_id, task_name, admins, owners, metadata): batch_list, signature = task_transaction_creation.create_task( txn_key=key, batch_key=self._key, task_id=task_id, task_name=task_name, admins=admins, owners=owners, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_task_admins(self, key, proposal_id, task_id, user_id, reason, metadata): batch_list, signature = task_transaction_creation.propose_add_task_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_task_admins(self, key, proposal_id, task_id, user_id, reason): batch_list, signature = task_transaction_creation.confirm_add_task_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_task_admins(self, key, proposal_id, task_id, user_id, reason): batch_list, signature = task_transaction_creation.reject_add_task_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_add_task_owners(self, key, proposal_id, task_id, user_id, reason, metadata): batch_list, signature = task_transaction_creation.propose_add_task_owner( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def confirm_add_task_owners(self, key, proposal_id, task_id, user_id, reason): batch_list, signature = task_transaction_creation.confirm_add_task_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def reject_add_task_owners(self, key, proposal_id, task_id, user_id, reason): batch_list, signature = task_transaction_creation.reject_add_task_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_delete_task_admins(self, key, proposal_id, task_id, user_id, reason, metadata): batch_list, signature = task_transaction_creation.propose_remove_task_admins( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10) def propose_delete_task_owners(self, key, proposal_id, task_id, user_id, reason, metadata): batch_list, signature = task_transaction_creation.propose_remove_task_owners( txn_key=key, batch_key=self._key, proposal_id=proposal_id, task_id=task_id, user_id=user_id, reason=reason, metadata=metadata, ) self._client.send_batches(batch_list) return self._client.get_statuses([signature], wait=10)
def _do_config_proposal_list(args): """Executes the 'proposal list' subcommand. Given a url, optional filters on prefix and public key, this command lists the current pending proposals for settings changes. """ rest_client = RestClient(args.url) state_leaf = rest_client.get_leaf( _key_to_address('sawtooth.config.vote.proposals')) def _accept(candidate, public_key, prefix): # Check to see if the first public key matches the given public key # (if it is not None). This public key belongs to the user that # created it. has_pub_key = (not public_key or candidate.votes[0].public_key == public_key) has_prefix = candidate.proposal.setting.startswith(prefix) return has_prefix and has_pub_key if state_leaf is not None: setting_bytes = b64decode(state_leaf['data']) setting = Setting() setting.ParseFromString(setting_bytes) candidates_bytes = None for entry in setting.entries: if entry.key == 'sawtooth.config.vote.proposals': candidates_bytes = entry.value decoded = b64decode(candidates_bytes) candidates_payload = ConfigCandidates() candidates_payload.ParseFromString(decoded) candidates = [ c for c in candidates_payload.candidates if _accept(c, args.public_key, args.filter) ] else: candidates = [] if args.format == 'default': for candidate in candidates: print('{}: {} => {}'.format(candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value)) elif args.format == 'csv': writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['PROPOSAL_ID', 'KEY', 'VALUE']) for candidate in candidates: writer.writerow([ candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value ]) elif args.format == 'json' or args.format == 'yaml': candidates_snapshot = \ {c.proposal_id: {c.proposal.setting: c.proposal.value} for c in candidates} if args.format == 'json': print(json.dumps(candidates_snapshot, indent=2, sort_keys=True)) else: print( yaml.dump(candidates_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def do_block(args): rest_client = RestClient(args.url) def print_json(data): print(json.dumps( data, indent=2, separators=(',', ': '), sort_keys=True)) def print_yaml(data): print(yaml.dump(data, default_flow_style=False)[0:-1]) if args.subcommand == 'list': blocks = rest_client.list_blocks() keys = ('num', 'block_id', 'batches', 'txns', 'signer') headers = (k.upper() if k != 'batches' else 'BATS' for k in keys) def get_block_data(block): batches = block.get('batches', []) txn_count = reduce( lambda t, b: t + len(b.get('transactions', [])), batches, 0) return ( block['header'].get('block_num', 0), block['header_signature'], len(batches), txn_count, block['header']['signer_pubkey'] ) if args.format == 'default': # Fit within 150 chars, without truncating block id print('{:<3} {:128.128} {:<4} {:<4} {:11.11}'.format(*headers)) for block in blocks: print('{:<3} {:128.128} {:<4} {:<4} {:8.8}...'.format( *get_block_data(block))) elif args.format == 'csv': try: writer = csv.writer(sys.stdout) writer.writerow(headers) for block in blocks: writer.writerow(get_block_data(block)) except csv.Error: raise CliException('Error writing CSV.') elif args.format == 'json' or args.format == 'yaml': block_data = list(map( lambda b: dict(zip(keys, get_block_data(b))), blocks )) if args.format == 'json': print_json(block_data) else: print_yaml(block_data) else: raise CliException('unknown format: {}'.format(args.format)) if args.subcommand == 'show': block = rest_client.get_block(args.block_id) if args.key: if args.key in block: print(block[args.key]) elif args.key in block['header']: print(block['header'][args.key]) else: raise CliException( 'key "{}" not found in block or header'.format(args.key)) else: if args.format == 'yaml': print_yaml(block) elif args.format == 'json': print_json(block) else: raise CliException('unknown format: {}'.format(args.format))
def do_block(args): """Runs the block list or block show command, printing output to the console Args: args: The parsed arguments sent to the command at runtime """ rest_client = RestClient(args.url, args.user) if args.subcommand == 'list': block_generator = rest_client.list_blocks() blocks = [] left = args.count for block in block_generator: blocks.append(block) left -= 1 if left <= 0: break keys = ('num', 'block_id', 'batches', 'txns', 'signer') headers = tuple(k.upper() if k != 'batches' else 'BATS' for k in keys) def parse_block_row(block): batches = block.get('batches', []) txns = [t for b in batches for t in b['transactions']] return ( block['header'].get('block_num', 0), block['header_signature'], len(batches), len(txns), block['header']['signer_public_key']) if args.format == 'default': fmt.print_terminal_table(headers, blocks, parse_block_row) elif args.format == 'csv': fmt.print_csv(headers, blocks, parse_block_row) elif args.format == 'json' or args.format == 'yaml': data = [{k: d for k, d in zip(keys, parse_block_row(b))} for b in blocks] if args.format == 'yaml': fmt.print_yaml(data) elif args.format == 'json': fmt.print_json(data) else: raise AssertionError('Missing handler: {}'.format(args.format)) else: raise AssertionError('Missing handler: {}'.format(args.format)) if args.subcommand == 'show': output = rest_client.get_block(args.block_id) if args.key: if args.key in output: output = output[args.key] elif args.key in output['header']: output = output['header'][args.key] else: raise CliException( 'key "{}" not found in block or header'.format(args.key)) if args.format == 'yaml': fmt.print_yaml(output) elif args.format == 'json': fmt.print_json(output) else: raise AssertionError('Missing handler: {}'.format(args.format))