29 from __future__
import absolute_import
31 from functools
import partial
40 from requests.adapters
import HTTPAdapter
41 from requests.packages.urllib3.util.retry
import Retry
43 from ddynamic_reconfigure_python.ddynamic_reconfigure
import DDynamicReconfigure
45 from .message_converter
import convert_dictionary_to_ros_message, convert_ros_message_to_dictionary
49 status_forcelist=[429],
52 A requests session that will retry on TOO_MANY_REQUESTS. 54 E.g. replace requests.get() with requests_retry_session().get() 56 session = session
or requests.Session()
61 backoff_factor=backoff_factor,
62 status_forcelist=status_forcelist,
64 adapter = HTTPAdapter(max_retries=retry)
65 session.mount(
'http://', adapter)
66 session.mount(
'https://', adapter)
72 def __init__(self, rest_name, ignored_parameters=[]):
78 rospy.init_node(rest_name +
'_client', log_level=rospy.INFO)
80 self.
host = rospy.get_param(
'~host',
'')
82 rospy.logerr(
'host is not set')
89 url =
'http://{}/api/v1/nodes/{}/parameters'.format(self.
host, self.
rest_name)
91 if res.status_code != 200:
92 rospy.logerr(
"Getting parameters failed with status code: %d", res.status_code)
95 except Exception
as e:
101 url =
'http://{}/api/v1/nodes/{}/parameters'.format(self.
host, self.
rest_name)
104 rospy.logdebug(
"set parameters response: %s", json.dumps(j, indent=2))
105 if 'return_code' in j
and j[
'return_code'][
'value'] != 0:
106 rospy.logwarn(
"Setting parameter failed: %s", j[
'return_code'][
'message'])
108 if res.status_code != 200:
109 rospy.logerr(
"Setting parameters failed with status code: %d", res.status_code)
112 except Exception
as e:
117 self.
ddr = DDynamicReconfigure(rospy.get_name())
120 def enum_method_from_param(p):
121 if p[
'type'] !=
'string':
123 enum_matches = re.findall(
r'.*\[(?P<enum>.+)\].*', p[
'description'])
126 enum_names = [str(e.strip())
for e
in enum_matches[0].split(
',')]
127 enum_list = [self.
ddr.const(n,
'str', n, n)
for n
in enum_names]
128 return self.
ddr.enum(enum_list, p[
'name'] +
'_enum')
130 for p
in rest_params:
132 edit_method = enum_method_from_param(p)
133 if p[
'type'] ==
'int32':
134 self.
ddr.add(p[
'name'],
'int', level, p[
'description'], p[
'default'], p[
'min'], p[
'max'])
135 elif p[
'type'] ==
'float64':
136 self.
ddr.add(p[
'name'],
'double', level, p[
'description'], p[
'default'], p[
'min'], p[
'max'])
137 elif p[
'type'] ==
'string':
138 self.
ddr.add(p[
'name'],
'str', level, p[
'description'], str(p[
'default']), edit_method=edit_method)
139 elif p[
'type'] ==
'bool':
140 self.
ddr.add(p[
'name'],
'bool', level, p[
'description'], p[
'default'])
142 rospy.logwarn(
"Unsupported parameter type: %s", p[
'type'])
147 rospy.logdebug(
"Received reconf call: " + str(config))
148 new_rest_params = [{
'name': n,
'value': config[n]}
for n
in self.
ddr.get_variable_names()
if n
in config]
151 for p
in returned_params:
152 if p[
'name']
not in config:
153 rospy.logerr(
"param %s not in config", p[
'name'])
155 config[p[
'name']] = p[
'value']
161 if request
is not None:
163 args = convert_ros_message_to_dictionary(request)
164 rospy.logdebug(
'calling {} with args: {}'.format(name, args))
166 url =
'http://{}/api/v1/nodes/{}/services/{}'.format(self.
host, self.
rest_name, name)
170 rospy.logdebug(
"{} rest response: {}".format(name, json.dumps(j, indent=2)))
171 rc = j[
'response'].get(
'return_code')
172 if rc
is not None and rc[
'value'] < 0:
173 rospy.logwarn(
"service {} returned an error: [{}] {}".format(name, rc[
'value'], rc[
'message']))
176 if srv_type
is not None:
177 response = convert_dictionary_to_ros_message(srv_type._response_class(), j[
'response'], strict_mode=
False)
179 response = j[
'response']
180 except Exception
as e:
182 if srv_type
is not None:
183 response = srv_type._response_class()
184 if hasattr(response,
'return_code'):
185 response.return_code.value = -1000
186 response.return_code.message = str(e)
190 """create a service and inject the REST-API service name""" 191 srv = rospy.Service(rospy.get_name() +
"/" + srv_name, srv_type, partial(callback, srv_name, srv_type))
def __init__(self, rest_name, ignored_parameters=[])
def call_rest_service(self, name, srv_type=None, request=None)
def _get_rest_parameters(self)
def _set_rest_parameters(self, parameters)
def add_rest_service(self, srv_type, srv_name, callback)
def _dyn_rec_callback(self, config, level)
def requests_retry_session(retries=3, backoff_factor=0.3, status_forcelist=[429], session=None)