def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) if args.node_name not in [n.full_name for n in node_names]: return 'Node not found' with DirectNode(args) as node: response = call_get_parameters(node=node, node_name=args.node_name, parameter_names=[args.name]) assert len(response.values) <= 1 # requested parameter not set if not response.values: return 'Parameter not set' # extract type specific value pvalue = response.values[0] if pvalue.type == ParameterType.PARAMETER_BOOL: label = 'Boolean value is:' value = pvalue.bool_value elif pvalue.type == ParameterType.PARAMETER_INTEGER: label = 'Integer value is:' value = pvalue.integer_value elif pvalue.type == ParameterType.PARAMETER_DOUBLE: label = 'Double value is:' value = pvalue.double_value elif pvalue.type == ParameterType.PARAMETER_STRING: label = 'String value is:' value = pvalue.string_value elif pvalue.type == ParameterType.PARAMETER_BYTE_ARRAY: label = 'Byte values are:' value = pvalue.byte_array_value elif pvalue.type == ParameterType.PARAMETER_BOOL_ARRAY: label = 'Boolean values are:' value = pvalue.bool_array_value elif pvalue.type == ParameterType.PARAMETER_INTEGER_ARRAY: label = 'Integer values are:' value = pvalue.integer_array_value elif pvalue.type == ParameterType.PARAMETER_DOUBLE_ARRAY: label = 'Double values are:' value = pvalue.double_array_value elif pvalue.type == ParameterType.PARAMETER_STRING_ARRAY: label = 'String values are:' value = pvalue.string_array_value elif pvalue.type == ParameterType.PARAMETER_NOT_SET: label = 'Parameter not set.' value = None else: return "Unknown parameter type '{pvalue.type}'" \ .format_map(locals()) # output response if not args.hide_type: print(label, value) if value is not None else print(label) else: print(value)
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node) with DirectNode(args) as node: container_node_names = find_container_node_names( node=node, node_names=node_names ) rclpy.init() node = rclpy.create_node(NODE_NAME_PREFIX + '_component_list_requester') try: if args.container_node_name is not None: if args.container_node_name not in [n.full_name for n in container_node_names]: return "Unable to find container node '" + args.container_node_name + "'" if not args.containers_only: components = get_container_components_info( node=node, remote_container_node_name=args.container_node_name ) if any(components): print(*['{} {}'.format(c.uid, c.name) for c in components], sep='\n') else: for n in container_node_names: print(n.full_name) if not args.containers_only: components = get_container_components_info( node=node, remote_container_node_name=n.full_name ) if any(components): print(*[ 2 * ' ' + '{} {}'.format(c.uid, c.name) for c in components ], sep='\n') finally: node.destroy_node() rclpy.shutdown()
def main(self, *, args): with NodeStrategy(args) as node: container_node_names = find_container_node_names( node=node, node_names=get_node_names(node=node)) if args.container_node_name not in [ n.full_name for n in container_node_names ]: return "Unable to find container node '" + args.container_node_name + "'" component_uid, component_name = load_component_into_container( node=node, remote_container_node_name=args.container_node_name, package_name=args.package_name, plugin_name=args.plugin_name, node_name=args.node_name, node_namespace=args.node_namespace, log_level=args.log_level, remap_rules=args.remap_rules, parameters=args.parameters, extra_arguments=args.extra_arguments) if not args.quiet: print("Loaded component {} into '{}' container node as '{}'". format(component_uid, args.container_node_name, component_name)) else: print('{} {}'.format(component_uid, component_name))
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node, include_hidden_nodes=True) if args.node_name in (n.full_name for n in node_names): with DirectNode(args) as node: print(args.node_name) subscribers = get_subscriber_info( node=node, remote_node_name=args.node_name) print(' Subscribers:') print_names_and_types(subscribers) publishers = get_publisher_info( node=node, remote_node_name=args.node_name) print(' Publishers:') print_names_and_types(publishers) services = get_service_info(node=node, remote_node_name=args.node_name) print(' Services:') print_names_and_types(services) actions_servers = get_action_server_info( node=node, remote_node_name=args.node_name) print(' Action Servers:') print_names_and_types(actions_servers) actions_clients = get_action_client_info( node=node, remote_node_name=args.node_name) print(' Action Clients:') print_names_and_types(actions_clients) else: return "Unable to find node '" + args.node_name + "'"
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node) with DirectNode(args) as node: container_node_names = find_container_node_names( node=node, node_names=node_names) if args.container_node_name is not None: if args.container_node_name not in [ n.full_name for n in container_node_names ]: return "Unable to find container node '" + args.container_node_name + "'" if not args.containers_only: components = get_container_components_info( node=node, remote_container_node_name=args.container_node_name) if any(components): print(*[ '{} {}'.format(c.uid, c.name) for c in components ], sep='\n') else: for n in container_node_names: print(n.full_name) if not args.containers_only: components = get_container_components_info( node=node, remote_container_node_name=n.full_name) if any(components): print(*[ ' ' + '{} {}'.format(c.uid, c.name) for c in components ], sep='\n')
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name not in [n.full_name for n in node_names]: return 'Node not found' with DirectNode(args) as node: parameter = Parameter() Parameter.name = args.name value = ParameterValue() value.type = ParameterType.PARAMETER_NOT_SET parameter.value = value response = call_set_parameters(node=node, node_name=args.node_name, parameters=[parameter]) # output response assert len(response.results) == 1 result = response.results[0] if result.successful: msg = 'Deleted parameter successfully' if result.reason: msg += ': ' + result.reason print(msg) else: msg = 'Deleting parameter failed' if result.reason: msg += ': ' + result.reason print(msg, file=sys.stderr)
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) if args.node_name not in node_names: return 'Node not found' with DirectNode(args) as node: parameter = Parameter() Parameter.name = args.name parameter.value = get_parameter_value(string_value=args.value) response = call_set_parameters(node=node, node_name=args.node_name, parameters=[parameter]) # output response assert len(response.results) == 1 result = response.results[0] if result.successful: msg = 'Set parameter successful' if result.reason: msg += ': ' + result.reason print(msg) else: msg = 'Setting parameter failed' if result.reason: msg += ': ' + result.reason print(msg, file=sys.stderr)
def container_node_name_completer(prefix, parsed_args, **kwargs): """Callable returning a list of container node names.""" with NodeStrategy(parsed_args) as node: return [ n.full_name for n in find_container_node_names( node=node, node_names=get_node_names(node=node)) ]
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node) with DirectNode(args) as node: container_node_names = find_container_node_names( node=node, node_names=node_names) rclpy.init() node = rclpy.create_node(NODE_NAME_PREFIX + '_component_load_requester') try: if args.container_node_name in [ n.full_name for n in container_node_names ]: return load_component_into_container( node=node, remote_container_node_name=args.container_node_name, package_name=args.package_name, plugin_name=args.plugin_name, node_name=args.node_name, node_namespace=args.node_namespace, log_level=args.log_level, remap_rules=args.remap_rules, parameters=args.parameters, extra_arguments=args.extra_arguments) else: return "Unable to find container node '" + args.container_node_name + "'" finally: node.destroy_node() rclpy.shutdown()
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name: if node_name not in [n.full_name for n in node_names]: return 'Node not found' node_names = [ n for n in node_names if node_name == n.full_name] regex_filter = getattr(args, 'filter') if regex_filter is not None: regex_filter = re.compile(regex_filter[0]) with DirectNode(args) as node: responses = {} for node_name in node_names: responses[node_name] = call_list_parameters( node=node, node_name=node_name.full_name, prefixes=args.param_prefixes) # print responses for node_name in sorted(responses.keys()): response = responses[node_name] if response is None: print( 'Wait for service timed out waiting for ' f'parameter services for node {node_name}') continue elif response.result() is None: e = response.exception() print( 'Exception while calling service of node ' f"'{node_name.full_name}': {e}", file=sys.stderr) continue response = response.result().result.names sorted_names = sorted(response) if regex_filter is not None: sorted_names = [name for name in sorted_names if regex_filter.match(name)] if not args.node_name and sorted_names: print(f'{node_name.full_name}:') # get descriptors for the node if needs to print parameter type name_to_type_map = {} if args.param_type is True: resp = call_describe_parameters( node=node, node_name=node_name.full_name, parameter_names=sorted_names) for descriptor in resp.descriptors: name_to_type_map[descriptor.name] = get_parameter_type_string( descriptor.type) for name in sorted_names: if args.param_type is True: param_type_str = name_to_type_map[name] print(f' {name} (type: {param_type_str})') else: print(f' {name}')
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names(node=node, include_hidden_nodes=args.include_hidden_nodes) absolute_node_name = get_absolute_node_name(args.node_name) node_name = parse_node_name(absolute_node_name) if absolute_node_name: if absolute_node_name not in [n.full_name for n in node_names]: return 'Node not found' if not os.path.isdir(args.output_dir): raise RuntimeError( f"'{args.output_dir}' is not a valid directory.") with DirectNode(args) as node: yaml_output = {node_name.full_name: {'ros__parameters': {}}} # retrieve values response = call_list_parameters(node=node, node_name=absolute_node_name) if response is None: raise RuntimeError( 'Wait for service timed out waiting for ' f'parameter services for node {node_name.full_name}') elif response.result() is None: e = response.exception() raise RuntimeError( 'Exception while calling service of node ' f"'{node_name.full_name}': {e}") response = response.result().result.names response = sorted(response) parameter_values = self.get_parameter_values(node, absolute_node_name, response) for param_name, pval in zip(response, parameter_values): self.insert_dict( yaml_output[node_name.full_name]['ros__parameters'], param_name, pval) if args.print: print( "WARNING: '--print' is deprecated; this utility prints to stdout by default", file=sys.stderr) if args.output_dir != '.': print( "WARNING: '--output-dir' is deprecated; use redirection to save to a file", file=sys.stderr) else: print(yaml.dump(yaml_output, default_flow_style=False)) return if absolute_node_name[0] == '/': file_name = absolute_node_name[1:].replace('/', '__') else: file_name = absolute_node_name.replace('/', '__') print('Saving to: ', os.path.join(args.output_dir, file_name + '.yaml')) with open(os.path.join(args.output_dir, file_name + '.yaml'), 'w') as yaml_file: yaml.dump(yaml_output, yaml_file, default_flow_style=False)
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node, include_hidden_nodes=args.all) if args.count_nodes: print(len(node_names)) elif node_names: print(*node_names, sep='\n')
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) if args.node_name: if args.node_name not in [n.full_name for n in node_names]: return 'Node not found' node_names = [ n for n in node_names if args.node_name == n.full_name ] with DirectNode(args) as node: clients = {} futures = {} # create clients for node_name in node_names: client = node.create_client( ListParameters, '{node_name.full_name}/list_parameters'.format_map( locals())) clients[node_name] = client # wait until all clients have been called while True: for node_name in [n for n in node_names if n not in futures]: # call as soon as ready client = clients[node_name] if client.service_is_ready(): request = ListParameters.Request() for prefix in args.param_prefixes: request.prefixes.append(prefix) future = client.call_async(request) futures[node_name] = future if len(futures) == len(clients): break rclpy.spin_once(node, timeout_sec=1.0) # wait for all responses for node_name in node_names: rclpy.spin_until_future_complete(node, futures[node_name]) # print responses for node_name in sorted(futures.keys()): future = futures[node_name] if future.result() is not None: if not args.node_name: print('{node_name.full_name}:'.format_map(locals())) response = future.result() for name in sorted(response.result.names): print(' {name}'.format_map(locals())) else: e = future.exception() print('Exception while calling service of node ' "'{node_name.full_name}': {e}".format_map(locals()), file=sys.stderr)
def get_node_info(node_name, include_hidden=False): node_names = get_node_names(node=_node, include_hidden_nodes=include_hidden) if node_name in [n.full_name for n in node_names]: # Only the name of each item is required as output. subscribers = get_node_subscriptions(node_name) publishers = get_node_publications(node_name) services = get_node_services(node_name) return subscribers, publishers, services
def test_find_container_node_names(): """Test find_container_node_names() API function.""" with NodeStrategy([]) as node: node_names = get_node_names(node=node) with DirectNode([]) as node: assert len(find_container_node_names(node=node, node_names=node_names)) == 0 assert len(find_container_node_names(node=node, node_names=[])) == 0
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name not in {n.full_name for n in node_names}: return 'Node not found' with DirectNode(args) as node: load_parameter_file(node=node, node_name=node_name, parameter_file=args.parameter_file, use_wildcard=not args.no_use_wildcard)
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden) count = [n.full_name for n in node_names].count(args.node_name) if count > 1: print(INFO_NONUNIQUE_WARNING_TEMPLATE.format( num_nodes=count, node_name=args.node_name), file=sys.stderr) if count > 0: with DirectNode(args) as node: print(args.node_name) subscribers = get_subscriber_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Subscribers:') print_names_and_types(subscribers) publishers = get_publisher_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Publishers:') print_names_and_types(publishers) service_servers = get_service_server_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Service Servers:') print_names_and_types(service_servers) service_clients = get_service_client_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Service Clients:') print_names_and_types(service_clients) actions_servers = get_action_server_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Action Servers:') print_names_and_types(actions_servers) actions_clients = get_action_client_info( node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden) print(' Action Clients:') print_names_and_types(actions_clients) else: return "Unable to find node '" + args.node_name + "'"
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node, include_hidden_nodes=args.all) if args.count_nodes: print(len(node_names)) elif node_names: sorted_names = sorted(n.full_name for n in node_names) if has_duplicates(sorted_names): print( 'WARNING: Be aware that are nodes in the graph that share an exact name, ' 'this can have unintended side effects.', file=sys.stderr) print(*sorted_names, sep='\n')
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name not in {n.full_name for n in node_names}: return 'Node not found' with DirectNode(args) as node: transitions = call_get_available_transitions( node=node, states={args.node_name: None}) transitions = transitions[args.node_name] if isinstance(transitions, Exception): return 'Exception while calling service of node ' \ "'{args.node_name}': {transitions}" \ .format_map(locals()) # identify requested transition for transition in [t.transition for t in transitions]: if transition.label == args.transition: break else: for transition in [t.transition for t in transitions]: if str(transition.id) == args.transition: break else: return \ 'Unknown transition requested, available ones are:' + \ ''.join( '\n- {t.transition.label} [{t.transition.id}]' .format_map(locals()) for t in transitions) results = call_change_states( node=node, transitions={args.node_name: transition}) result = results[args.node_name] # output response if isinstance(result, Exception): print('Exception while calling service of node ' "'{args.node_name}': {result}".format_map(locals()), file=sys.stderr) elif result: print('Transitioning successful') else: print('Transitioning failed', file=sys.stderr)
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name not in {n.full_name for n in node_names}: return 'Node not found' with DirectNode(args) as node: response = call_describe_parameters( node=node, node_name=args.node_name, parameter_names=args.parameter_names or None) # output response for descriptor in response.descriptors: self._print_descriptor(descriptor)
def main(self, *, args): with NodeStrategy(args) as node: node_names = get_node_names(node=node) with DirectNode(args) as node: container_node_names = find_container_node_names( node=node, node_names=node_names) rclpy.init() node = rclpy.create_node(NODE_NAME_PREFIX + '_component_load_requester') if args.container_node_name in [ n.full_name for n in container_node_names ]: return unload_component_from_container( node=node, remote_container_node_name=args.container_node_name, component_uids=args.component_uid) else: return "Unable to find container node '" + args.container_node_name + "'"
def ros2node(self, domain_id): """ 'ros2 node list' fetched from ros2cli and more """ print("Exploring ROS_DOMAIN_ID: " + str(domain_id) + ' for nodes') os.environ['ROS_DOMAIN_ID'] = str(domain_id) with NodeStrategy("-a") as node: node_names = get_node_names(node=node, include_hidden_nodes="-a") nodes = sorted(n.full_name for n in node_names) output_node = {} for nodo in nodes: # # Abstractions from helper2 # output_node = ROS2node() # output_node.name = nodo # output_node.domain_id = domain_id # output_node.namespace = output_node.name[:(output_node.name.rfind("/") + 1)] # fetch the substring until the last "/" # Abstractions using a list[dict] as defined above (see self.processed_nodes): #output_node = {"name": nodo, "domain": domain_id} #output_node["namespace"] = output_node["name"][:(output_node["name"].rfind("/") + 1)] # fetch the substring until the last "/" with DirectNode(nodo) as node: if str(nodo) != '/_ros2cli_daemon_0': output_node[nodo] = { 'domain': domain_id, 'subscribers': get_subscriber_info(node=node, remote_node_name=nodo), 'publishers': get_publisher_info(node=node, remote_node_name=nodo), 'services': get_service_info(node=node, remote_node_name=nodo), 'actionservers': get_action_server_info(node=node, remote_node_name=nodo), 'actionclient': get_action_client_info(node=node, remote_node_name=nodo) } self.processed_nodes.append(output_node)
def main(self, *, args): with NodeStrategy(args) as node: container_node_names = find_container_node_names( node=node, node_names=get_node_names(node=node)) if args.container_node_name not in [ n.full_name for n in container_node_names ]: return "Unable to find container node '" + args.container_node_name + "'" for uid, error, reason in unload_component_from_container( node=node, remote_container_node_name=args.container_node_name, component_uids=args.component_uid): if error: return "Failed to unload component {} from '{}' container node\n {}".format( uid, args.container_node_name, reason.capitalize()) if not args.quiet: print("Unloaded component {} from '{}' container node". format(uid, args.container_node_name)) else: print(uid)
def main(self, *, args): with NodeStrategy(args) as node: container_node_names = find_container_node_names( node=node, node_names=get_node_names(node=node)) if args.container_node_name is not None: if args.container_node_name not in [ n.full_name for n in container_node_names ]: return "Unable to find container node '" + args.container_node_name + "'" if not args.containers_only: ok, outcome = get_components_in_container( node=node, remote_container_node_name=args.container_node_name) if not ok: return f'{outcome} when listing components in {args.container_node_name}' if any(outcome): print(*[ f'{component.uid} {component.name}' for component in outcome ], sep='\n') else: results = get_components_in_containers( node=node, remote_containers_node_names=[ n.full_name for n in container_node_names ]) for container_node_name, (ok, outcome) in results.items(): print(container_node_name) if not args.containers_only: if not ok: print(f'{outcome} when listing components') continue if any(outcome): print(*[ f' {component.uid} {component.name}' for component in outcome ], sep='\n')
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) absolute_node_name = get_absolute_node_name(args.node_name) node_name = parse_node_name(absolute_node_name) if absolute_node_name: if absolute_node_name not in [n.full_name for n in node_names]: return 'Node not found' if not os.path.isdir(args.output_dir): raise RuntimeError( f"'{args.output_dir}' is not a valid directory.") with DirectNode(args) as node: # create client service_name = f'{absolute_node_name}/list_parameters' client = node.create_client(ListParameters, service_name) client.wait_for_service() if not client.service_is_ready(): raise RuntimeError(f"Could not reach service '{service_name}'") request = ListParameters.Request() future = client.call_async(request) # wait for response rclpy.spin_until_future_complete(node, future) yaml_output = {node_name.name: {'ros__parameters': {}}} # retrieve values if future.result() is not None: response = future.result() for param_name in sorted(response.result.names): pval = self.get_parameter_value(node, absolute_node_name, param_name) self.insert_dict( yaml_output[node_name.name]['ros__parameters'], param_name, pval) else: e = future.exception() raise RuntimeError('Exception while calling service of node ' f"'{node_name.full_name}': {e}") if args.print: print(yaml.dump(yaml_output, default_flow_style=False)) return if absolute_node_name[0] == '/': file_name = absolute_node_name[1:].replace('/', '__') else: file_name = absolute_node_name.replace('/', '__') print('Saving to: ', os.path.join(args.output_dir, file_name + '.yaml')) with open(os.path.join(args.output_dir, file_name + '.yaml'), 'w') as yaml_file: yaml.dump(yaml_output, yaml_file, default_flow_style=False)
def get_nodes(include_hidden=False): """ Returns a list of all the nodes registered in the ROS system """ node_names = get_node_names(node=_node, include_hidden_nodes=include_hidden) full_names = [node_name.full_name for node_name in node_names] return full_names
def main(self, *, args): # noqa: D102 with NodeStrategy(args) as node: node_names = get_node_names( node=node, include_hidden_nodes=args.include_hidden_nodes) node_name = get_absolute_node_name(args.node_name) if node_name: if node_name not in [n.full_name for n in node_names]: return 'Node not found' node_names = [n for n in node_names if node_name == n.full_name] regex_filter = getattr(args, 'filter') if regex_filter is not None: regex_filter = re.compile(regex_filter[0]) with DirectNode(args) as node: service_names = get_service_names( node=node, include_hidden_services=args.include_hidden_nodes) clients = {} futures = {} # create clients for nodes which have the service for node_name in node_names: service_name = f'{node_name.full_name}/list_parameters' if service_name in service_names: client = node.create_client(ListParameters, service_name) clients[node_name] = client # wait until all clients have been called while True: for node_name in [ n for n in clients.keys() if n not in futures ]: # call as soon as ready client = clients[node_name] if client.service_is_ready(): request = ListParameters.Request() for prefix in args.param_prefixes: request.prefixes.append(prefix) future = client.call_async(request) futures[node_name] = future if len(futures) == len(clients): break rclpy.spin_once(node, timeout_sec=1.0) # wait for all responses for future in futures.values(): rclpy.spin_until_future_complete(node, future, timeout_sec=1.0) # print responses for node_name in sorted(futures.keys()): future = futures[node_name] if future.result() is None: e = future.exception() print( 'Exception while calling service of node ' f"'{node_name.full_name}': {e}", file=sys.stderr) response = future.result() sorted_names = sorted(response.result.names) if regex_filter is not None: sorted_names = [ name for name in sorted_names if regex_filter.match(name) ] if not args.node_name and sorted_names: print(f'{node_name.full_name}:') # get descriptors for the node if needs to print parameter type name_to_type_map = {} if args.param_type is True: resp = call_describe_parameters( node=node, node_name=node_name.full_name, parameter_names=sorted_names) for descriptor in resp.descriptors: name_to_type_map[ descriptor.name] = get_parameter_type_string( descriptor.type) for name in sorted_names: if args.param_type is True: param_type_str = name_to_type_map[name] print(f' {name} (type: {param_type_str})') else: print(f' {name}')