1 | # Licensed to the StackStorm, Inc ('StackStorm') under one or more |
||
2 | # contributor license agreements. See the NOTICE file distributed with |
||
3 | # this work for additional information regarding copyright ownership. |
||
4 | # The ASF licenses this file to You under the Apache License, Version 2.0 |
||
5 | # (the "License"); you may not use this file except in compliance with |
||
6 | # the License. You may obtain a copy of the License at |
||
7 | # |
||
8 | # http://www.apache.org/licenses/LICENSE-2.0 |
||
9 | # |
||
10 | # Unless required by applicable law or agreed to in writing, software |
||
11 | # distributed under the License is distributed on an "AS IS" BASIS, |
||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
13 | # See the License for the specific language governing permissions and |
||
14 | # limitations under the License. |
||
15 | |||
16 | from __future__ import absolute_import |
||
17 | import os |
||
18 | import json |
||
19 | import logging |
||
20 | from functools import wraps |
||
21 | |||
22 | import six |
||
23 | from six.moves import urllib |
||
24 | from six.moves import http_client |
||
25 | |||
26 | from st2client.utils import httpclient |
||
27 | |||
28 | |||
29 | LOG = logging.getLogger(__name__) |
||
30 | |||
31 | |||
32 | def add_auth_token_to_kwargs_from_env(func): |
||
33 | @wraps(func) |
||
34 | def decorate(*args, **kwargs): |
||
35 | if not kwargs.get('token') and os.environ.get('ST2_AUTH_TOKEN', None): |
||
36 | kwargs['token'] = os.environ.get('ST2_AUTH_TOKEN') |
||
37 | if not kwargs.get('api_key') and os.environ.get('ST2_API_KEY', None): |
||
38 | kwargs['api_key'] = os.environ.get('ST2_API_KEY') |
||
39 | |||
40 | return func(*args, **kwargs) |
||
41 | return decorate |
||
42 | |||
43 | |||
44 | class Resource(object): |
||
45 | |||
46 | # An alias to use for the resource if different than the class name. |
||
47 | _alias = None |
||
48 | |||
49 | # Display name of the resource. This may be different than its resource |
||
50 | # name specifically when the resource name is composed of multiple words. |
||
51 | _display_name = None |
||
52 | |||
53 | # URL path for the resource. |
||
54 | _url_path = None |
||
55 | |||
56 | # Plural form of the resource name. This will be used to build the |
||
57 | # latter part of the REST URL. |
||
58 | _plural = None |
||
59 | |||
60 | # Plural form of the resource display name. |
||
61 | _plural_display_name = None |
||
62 | |||
63 | # A list of class attributes which will be included in __repr__ return value |
||
64 | _repr_attributes = [] |
||
65 | |||
66 | def __init__(self, *args, **kwargs): |
||
67 | for k, v in six.iteritems(kwargs): |
||
68 | setattr(self, k, v) |
||
69 | |||
70 | def to_dict(self, exclude_attributes=None): |
||
71 | """ |
||
72 | Return a dictionary representation of this object. |
||
73 | |||
74 | :param exclude_attributes: Optional list of attributes to exclude. |
||
75 | :type exclude_attributes: ``list`` |
||
76 | |||
77 | :rtype: ``dict`` |
||
78 | """ |
||
79 | exclude_attributes = exclude_attributes or [] |
||
80 | |||
81 | attributes = list(self.__dict__.keys()) |
||
82 | attributes = [attr for attr in attributes if not attr.startswith('__') and |
||
83 | attr not in exclude_attributes] |
||
84 | |||
85 | result = {} |
||
86 | for attribute in attributes: |
||
87 | value = getattr(self, attribute, None) |
||
88 | result[attribute] = value |
||
89 | |||
90 | return result |
||
91 | |||
92 | @classmethod |
||
93 | def get_alias(cls): |
||
94 | return cls._alias if cls._alias else cls.__name__ |
||
95 | |||
96 | @classmethod |
||
97 | def get_display_name(cls): |
||
98 | return cls._display_name if cls._display_name else cls.__name__ |
||
99 | |||
100 | @classmethod |
||
101 | def get_plural_name(cls): |
||
102 | if not cls._plural: |
||
103 | raise Exception('The %s class is missing class attributes ' |
||
104 | 'in its definition.' % cls.__name__) |
||
105 | return cls._plural |
||
106 | |||
107 | @classmethod |
||
108 | def get_plural_display_name(cls): |
||
109 | return (cls._plural_display_name |
||
110 | if cls._plural_display_name |
||
111 | else cls._plural) |
||
112 | |||
113 | @classmethod |
||
114 | def get_url_path_name(cls): |
||
115 | if cls._url_path: |
||
116 | return cls._url_path |
||
117 | |||
118 | return cls.get_plural_name().lower() |
||
119 | |||
120 | def serialize(self): |
||
121 | return dict((k, v) |
||
122 | for k, v in six.iteritems(self.__dict__) |
||
123 | if not k.startswith('_')) |
||
124 | |||
125 | @classmethod |
||
126 | def deserialize(cls, doc): |
||
127 | if type(doc) is not dict: |
||
128 | doc = json.loads(doc) |
||
129 | return cls(**doc) |
||
130 | |||
131 | def __str__(self): |
||
132 | return str(self.__repr__()) |
||
133 | |||
134 | def __repr__(self): |
||
135 | if not self._repr_attributes: |
||
136 | return super(Resource, self).__repr__() |
||
137 | |||
138 | attributes = [] |
||
139 | for attribute in self._repr_attributes: |
||
140 | value = getattr(self, attribute, None) |
||
141 | attributes.append('%s=%s' % (attribute, value)) |
||
142 | |||
143 | attributes = ','.join(attributes) |
||
144 | class_name = self.__class__.__name__ |
||
145 | result = '<%s %s>' % (class_name, attributes) |
||
146 | return result |
||
147 | |||
148 | |||
149 | class ResourceManager(object): |
||
150 | |||
151 | def __init__(self, resource, endpoint, cacert=None, debug=False): |
||
152 | self.resource = resource |
||
153 | self.debug = debug |
||
154 | self.client = httpclient.HTTPClient(endpoint, cacert=cacert, debug=debug) |
||
155 | |||
156 | @staticmethod |
||
157 | def handle_error(response): |
||
158 | try: |
||
159 | content = response.json() |
||
160 | fault = content.get('faultstring', '') if content else '' |
||
161 | if fault: |
||
162 | response.reason += '\nMESSAGE: %s' % fault |
||
163 | except Exception as e: |
||
164 | response.reason += ('\nUnable to retrieve detailed message ' |
||
165 | 'from the HTTP response. %s\n' % str(e)) |
||
166 | response.raise_for_status() |
||
167 | |||
168 | @add_auth_token_to_kwargs_from_env |
||
169 | def get_all(self, **kwargs): |
||
170 | # TODO: This is ugly, stop abusing kwargs |
||
171 | url = '/%s' % self.resource.get_url_path_name() |
||
172 | limit = kwargs.pop('limit', None) |
||
173 | pack = kwargs.pop('pack', None) |
||
174 | prefix = kwargs.pop('prefix', None) |
||
175 | user = kwargs.pop('user', None) |
||
176 | |||
177 | params = kwargs.pop('params', {}) |
||
178 | |||
179 | if limit: |
||
180 | params['limit'] = limit |
||
181 | |||
182 | if pack: |
||
183 | params['pack'] = pack |
||
184 | |||
185 | if prefix: |
||
186 | params['prefix'] = prefix |
||
187 | |||
188 | if user: |
||
189 | params['user'] = user |
||
190 | |||
191 | response = self.client.get(url=url, params=params, **kwargs) |
||
192 | if response.status_code != http_client.OK: |
||
193 | self.handle_error(response) |
||
194 | return [self.resource.deserialize(item) |
||
195 | for item in response.json()] |
||
196 | |||
197 | @add_auth_token_to_kwargs_from_env |
||
198 | def get_by_id(self, id, **kwargs): |
||
0 ignored issues
–
show
|
|||
199 | url = '/%s/%s' % (self.resource.get_url_path_name(), id) |
||
200 | response = self.client.get(url, **kwargs) |
||
201 | if response.status_code == http_client.NOT_FOUND: |
||
202 | return None |
||
203 | if response.status_code != http_client.OK: |
||
204 | self.handle_error(response) |
||
205 | return self.resource.deserialize(response.json()) |
||
206 | |||
207 | @add_auth_token_to_kwargs_from_env |
||
208 | def get_property(self, id_, property_name, self_deserialize=True, **kwargs): |
||
209 | """ |
||
210 | Gets a property of a Resource. |
||
211 | id_ : Id of the resource |
||
212 | property_name: Name of the property |
||
213 | self_deserialize: #Implies use the deserialize method implemented by this resource. |
||
214 | """ |
||
215 | token = kwargs.pop('token', None) |
||
216 | api_key = kwargs.pop('api_key', None) |
||
217 | |||
218 | if kwargs: |
||
219 | url = '/%s/%s/%s/?%s' % (self.resource.get_url_path_name(), id_, property_name, |
||
220 | urllib.parse.urlencode(kwargs)) |
||
221 | else: |
||
222 | url = '/%s/%s/%s/' % (self.resource.get_url_path_name(), id_, property_name) |
||
223 | |||
224 | if token: |
||
225 | response = self.client.get(url, token=token) |
||
226 | elif api_key: |
||
227 | response = self.client.get(url, api_key=api_key) |
||
228 | else: |
||
229 | response = self.client.get(url) |
||
230 | |||
231 | if response.status_code == http_client.NOT_FOUND: |
||
232 | return None |
||
233 | if response.status_code != http_client.OK: |
||
234 | self.handle_error(response) |
||
235 | |||
236 | if self_deserialize: |
||
237 | return [self.resource.deserialize(item) for item in response.json()] |
||
238 | else: |
||
239 | return response.json() |
||
240 | |||
241 | @add_auth_token_to_kwargs_from_env |
||
242 | def get_by_ref_or_id(self, ref_or_id, **kwargs): |
||
243 | return self.get_by_id(id=ref_or_id, **kwargs) |
||
244 | |||
245 | def _query_details(self, **kwargs): |
||
246 | if not kwargs: |
||
247 | raise Exception('Query parameter is not provided.') |
||
248 | |||
249 | token = kwargs.get('token', None) |
||
250 | api_key = kwargs.get('api_key', None) |
||
251 | params = kwargs.get('params', {}) |
||
252 | |||
253 | for k, v in six.iteritems(kwargs): |
||
254 | # Note: That's a special case to support api_key and token kwargs |
||
255 | if k not in ['token', 'api_key', 'params']: |
||
256 | params[k] = v |
||
257 | |||
258 | url = '/%s/?%s' % (self.resource.get_url_path_name(), |
||
259 | urllib.parse.urlencode(params)) |
||
260 | |||
261 | if token: |
||
262 | response = self.client.get(url, token=token) |
||
263 | elif api_key: |
||
264 | response = self.client.get(url, api_key=api_key) |
||
265 | else: |
||
266 | response = self.client.get(url) |
||
267 | |||
268 | if response.status_code == http_client.NOT_FOUND: |
||
269 | # for query and query_with_count |
||
270 | return [], None |
||
271 | if response.status_code != http_client.OK: |
||
272 | self.handle_error(response) |
||
273 | items = response.json() |
||
274 | instances = [self.resource.deserialize(item) for item in items] |
||
275 | return instances, response |
||
276 | |||
277 | @add_auth_token_to_kwargs_from_env |
||
278 | def query(self, **kwargs): |
||
279 | instances, _ = self._query_details(**kwargs) |
||
280 | return instances |
||
281 | |||
282 | @add_auth_token_to_kwargs_from_env |
||
283 | def query_with_count(self, **kwargs): |
||
284 | instances, response = self._query_details(**kwargs) |
||
285 | if response and 'X-Total-Count' in response.headers: |
||
286 | return (instances, int(response.headers['X-Total-Count'])) |
||
287 | else: |
||
288 | return (instances, None) |
||
289 | |||
290 | @add_auth_token_to_kwargs_from_env |
||
291 | def get_by_name(self, name, **kwargs): |
||
292 | instances = self.query(name=name, **kwargs) |
||
293 | if not instances: |
||
294 | return None |
||
295 | else: |
||
296 | if len(instances) > 1: |
||
297 | raise Exception('More than one %s named "%s" are found.' % |
||
298 | (self.resource.__name__.lower(), name)) |
||
299 | return instances[0] |
||
300 | |||
301 | @add_auth_token_to_kwargs_from_env |
||
302 | def create(self, instance, **kwargs): |
||
303 | url = '/%s' % self.resource.get_url_path_name() |
||
304 | response = self.client.post(url, instance.serialize(), **kwargs) |
||
305 | if response.status_code != http_client.OK: |
||
306 | self.handle_error(response) |
||
307 | instance = self.resource.deserialize(response.json()) |
||
308 | return instance |
||
309 | |||
310 | @add_auth_token_to_kwargs_from_env |
||
311 | def update(self, instance, **kwargs): |
||
312 | url = '/%s/%s' % (self.resource.get_url_path_name(), instance.id) |
||
313 | response = self.client.put(url, instance.serialize(), **kwargs) |
||
314 | if response.status_code != http_client.OK: |
||
315 | self.handle_error(response) |
||
316 | instance = self.resource.deserialize(response.json()) |
||
317 | return instance |
||
318 | |||
319 | @add_auth_token_to_kwargs_from_env |
||
320 | def delete(self, instance, **kwargs): |
||
321 | url = '/%s/%s' % (self.resource.get_url_path_name(), instance.id) |
||
322 | response = self.client.delete(url, **kwargs) |
||
323 | |||
324 | if response.status_code not in [http_client.OK, |
||
325 | http_client.NO_CONTENT, |
||
326 | http_client.NOT_FOUND]: |
||
327 | self.handle_error(response) |
||
328 | return False |
||
329 | |||
330 | return True |
||
331 | |||
332 | @add_auth_token_to_kwargs_from_env |
||
333 | def delete_by_id(self, instance_id, **kwargs): |
||
334 | url = '/%s/%s' % (self.resource.get_url_path_name(), instance_id) |
||
335 | response = self.client.delete(url, **kwargs) |
||
336 | if response.status_code not in [http_client.OK, |
||
337 | http_client.NO_CONTENT, |
||
338 | http_client.NOT_FOUND]: |
||
339 | self.handle_error(response) |
||
340 | return False |
||
341 | try: |
||
342 | resp_json = response.json() |
||
343 | if resp_json: |
||
344 | return resp_json |
||
345 | except: |
||
346 | pass |
||
347 | return True |
||
348 | |||
349 | |||
350 | class ActionAliasResourceManager(ResourceManager): |
||
351 | def __init__(self, resource, endpoint, cacert=None, debug=False): |
||
0 ignored issues
–
show
The
__init__ method of the super-class ResourceManager is not called.
It is generally advisable to initialize the super-class by calling its class SomeParent:
def __init__(self):
self.x = 1
class SomeChild(SomeParent):
def __init__(self):
# Initialize the super class
SomeParent.__init__(self)
Loading history...
|
|||
352 | self.resource = resource |
||
353 | self.debug = debug |
||
354 | self.client = httpclient.HTTPClient(root=endpoint, cacert=cacert, debug=debug) |
||
355 | |||
356 | @add_auth_token_to_kwargs_from_env |
||
357 | def match(self, instance, **kwargs): |
||
358 | url = '/%s/match' % self.resource.get_url_path_name() |
||
359 | response = self.client.post(url, instance.serialize(), **kwargs) |
||
360 | if response.status_code != http_client.OK: |
||
361 | self.handle_error(response) |
||
362 | match = response.json() |
||
363 | return (self.resource.deserialize(match['actionalias']), match['representation']) |
||
364 | |||
365 | |||
366 | class ActionAliasExecutionManager(ResourceManager): |
||
367 | @add_auth_token_to_kwargs_from_env |
||
368 | def match_and_execute(self, instance, **kwargs): |
||
369 | url = '/%s/match_and_execute' % self.resource.get_url_path_name() |
||
370 | response = self.client.post(url, instance.serialize(), **kwargs) |
||
371 | |||
372 | if response.status_code != http_client.OK: |
||
373 | self.handle_error(response) |
||
374 | instance = self.resource.deserialize(response.json()) |
||
375 | return instance |
||
376 | |||
377 | |||
378 | class LiveActionResourceManager(ResourceManager): |
||
379 | @add_auth_token_to_kwargs_from_env |
||
380 | def re_run(self, execution_id, parameters=None, tasks=None, no_reset=None, **kwargs): |
||
381 | url = '/%s/%s/re_run' % (self.resource.get_url_path_name(), execution_id) |
||
382 | |||
383 | tasks = tasks or [] |
||
384 | no_reset = no_reset or [] |
||
385 | |||
386 | if list(set(no_reset) - set(tasks)): |
||
387 | raise ValueError('List of tasks to reset does not match the tasks to rerun.') |
||
388 | |||
389 | data = { |
||
390 | 'parameters': parameters or {}, |
||
391 | 'tasks': tasks, |
||
392 | 'reset': list(set(tasks) - set(no_reset)) |
||
393 | } |
||
394 | |||
395 | response = self.client.post(url, data, **kwargs) |
||
396 | if response.status_code != http_client.OK: |
||
397 | self.handle_error(response) |
||
398 | |||
399 | instance = self.resource.deserialize(response.json()) |
||
400 | return instance |
||
401 | |||
402 | @add_auth_token_to_kwargs_from_env |
||
403 | def get_output(self, execution_id, output_type=None, **kwargs): |
||
404 | url = '/%s/%s/output' % (self.resource.get_url_path_name(), execution_id) |
||
405 | |||
406 | if output_type: |
||
407 | url += '?' + urllib.parse.urlencode({'output_type': output_type}) |
||
408 | |||
409 | response = self.client.get(url, **kwargs) |
||
410 | if response.status_code != http_client.OK: |
||
411 | self.handle_error(response) |
||
412 | |||
413 | return response.text |
||
414 | |||
415 | @add_auth_token_to_kwargs_from_env |
||
416 | def pause(self, execution_id, **kwargs): |
||
417 | url = '/%s/%s' % (self.resource.get_url_path_name(), execution_id) |
||
418 | data = {'status': 'pausing'} |
||
419 | |||
420 | response = self.client.put(url, data, **kwargs) |
||
421 | |||
422 | if response.status_code != http_client.OK: |
||
423 | self.handle_error(response) |
||
424 | |||
425 | return self.resource.deserialize(response.json()) |
||
426 | |||
427 | @add_auth_token_to_kwargs_from_env |
||
428 | def resume(self, execution_id, **kwargs): |
||
429 | url = '/%s/%s' % (self.resource.get_url_path_name(), execution_id) |
||
430 | data = {'status': 'resuming'} |
||
431 | |||
432 | response = self.client.put(url, data, **kwargs) |
||
433 | |||
434 | if response.status_code != http_client.OK: |
||
435 | self.handle_error(response) |
||
436 | |||
437 | return self.resource.deserialize(response.json()) |
||
438 | |||
439 | |||
440 | class InquiryResourceManager(ResourceManager): |
||
441 | |||
442 | @add_auth_token_to_kwargs_from_env |
||
443 | def respond(self, inquiry_id, inquiry_response, **kwargs): |
||
444 | """ |
||
445 | Update st2.inquiry.respond action |
||
446 | Update st2client respond command to use this? |
||
447 | """ |
||
448 | url = '/%s/%s' % (self.resource.get_url_path_name(), inquiry_id) |
||
449 | |||
450 | payload = { |
||
451 | "id": inquiry_id, |
||
452 | "response": inquiry_response |
||
453 | } |
||
454 | |||
455 | response = self.client.put(url, payload, **kwargs) |
||
456 | |||
457 | if response.status_code != http_client.OK: |
||
458 | self.handle_error(response) |
||
459 | |||
460 | return self.resource.deserialize(response.json()) |
||
461 | |||
462 | |||
463 | class TriggerInstanceResourceManager(ResourceManager): |
||
464 | @add_auth_token_to_kwargs_from_env |
||
465 | def re_emit(self, trigger_instance_id, **kwargs): |
||
466 | url = '/%s/%s/re_emit' % (self.resource.get_url_path_name(), trigger_instance_id) |
||
467 | response = self.client.post(url, None, **kwargs) |
||
468 | if response.status_code != http_client.OK: |
||
469 | self.handle_error(response) |
||
470 | return response.json() |
||
471 | |||
472 | |||
473 | class AsyncRequest(Resource): |
||
474 | pass |
||
475 | |||
476 | |||
477 | class PackResourceManager(ResourceManager): |
||
478 | @add_auth_token_to_kwargs_from_env |
||
479 | def install(self, packs, force=False, python3=False, **kwargs): |
||
480 | url = '/%s/install' % (self.resource.get_url_path_name()) |
||
481 | payload = { |
||
482 | 'packs': packs, |
||
483 | 'force': force, |
||
484 | 'python3': python3 |
||
485 | } |
||
486 | response = self.client.post(url, payload, **kwargs) |
||
487 | if response.status_code != http_client.OK: |
||
488 | self.handle_error(response) |
||
489 | instance = AsyncRequest.deserialize(response.json()) |
||
490 | return instance |
||
491 | |||
492 | @add_auth_token_to_kwargs_from_env |
||
493 | def remove(self, packs, **kwargs): |
||
494 | url = '/%s/uninstall' % (self.resource.get_url_path_name()) |
||
495 | response = self.client.post(url, {'packs': packs}, **kwargs) |
||
496 | if response.status_code != http_client.OK: |
||
497 | self.handle_error(response) |
||
498 | instance = AsyncRequest.deserialize(response.json()) |
||
499 | return instance |
||
500 | |||
501 | @add_auth_token_to_kwargs_from_env |
||
502 | def search(self, args, ignore_errors=False, **kwargs): |
||
503 | url = '/%s/index/search' % (self.resource.get_url_path_name()) |
||
504 | if 'query' in vars(args): |
||
505 | payload = {'query': args.query} |
||
506 | else: |
||
507 | payload = {'pack': args.pack} |
||
508 | |||
509 | response = self.client.post(url, payload, **kwargs) |
||
510 | |||
511 | if response.status_code != http_client.OK: |
||
512 | if ignore_errors: |
||
513 | return None |
||
514 | |||
515 | self.handle_error(response) |
||
516 | data = response.json() |
||
517 | if isinstance(data, list): |
||
518 | return [self.resource.deserialize(item) for item in data] |
||
519 | else: |
||
520 | return self.resource.deserialize(data) if data else None |
||
521 | |||
522 | @add_auth_token_to_kwargs_from_env |
||
523 | def register(self, packs=None, types=None, **kwargs): |
||
524 | url = '/%s/register' % (self.resource.get_url_path_name()) |
||
525 | payload = {} |
||
526 | if types: |
||
527 | payload['types'] = types |
||
528 | if packs: |
||
529 | payload['packs'] = packs |
||
530 | response = self.client.post(url, payload, **kwargs) |
||
531 | if response.status_code != http_client.OK: |
||
532 | self.handle_error(response) |
||
533 | instance = self.resource.deserialize(response.json()) |
||
534 | return instance |
||
535 | |||
536 | |||
537 | class ConfigManager(ResourceManager): |
||
538 | @add_auth_token_to_kwargs_from_env |
||
539 | def update(self, instance, **kwargs): |
||
540 | url = '/%s/%s' % (self.resource.get_url_path_name(), instance.pack) |
||
541 | response = self.client.put(url, instance.values, **kwargs) |
||
542 | if response.status_code != http_client.OK: |
||
543 | self.handle_error(response) |
||
544 | instance = self.resource.deserialize(response.json()) |
||
545 | return instance |
||
546 | |||
547 | |||
548 | class WebhookManager(ResourceManager): |
||
549 | def __init__(self, resource, endpoint, cacert=None, debug=False): |
||
0 ignored issues
–
show
The
__init__ method of the super-class ResourceManager is not called.
It is generally advisable to initialize the super-class by calling its class SomeParent:
def __init__(self):
self.x = 1
class SomeChild(SomeParent):
def __init__(self):
# Initialize the super class
SomeParent.__init__(self)
Loading history...
|
|||
550 | self.resource = resource |
||
551 | self.debug = debug |
||
552 | self.client = httpclient.HTTPClient(root=endpoint, cacert=cacert, debug=debug) |
||
553 | |||
554 | @add_auth_token_to_kwargs_from_env |
||
555 | def post_generic_webhook(self, trigger, payload=None, trace_tag=None, **kwargs): |
||
556 | url = '/webhooks/st2' |
||
557 | |||
558 | headers = {} |
||
559 | data = { |
||
560 | 'trigger': trigger, |
||
561 | 'payload': payload or {} |
||
562 | } |
||
563 | |||
564 | if trace_tag: |
||
565 | headers['St2-Trace-Tag'] = trace_tag |
||
566 | |||
567 | response = self.client.post(url, data=data, headers=headers, **kwargs) |
||
568 | |||
569 | if response.status_code != http_client.OK: |
||
570 | self.handle_error(response) |
||
571 | |||
572 | return response.json() |
||
573 | |||
574 | @add_auth_token_to_kwargs_from_env |
||
575 | def match(self, instance, **kwargs): |
||
576 | url = '/%s/match' % self.resource.get_url_path_name() |
||
577 | response = self.client.post(url, instance.serialize(), **kwargs) |
||
578 | if response.status_code != http_client.OK: |
||
579 | self.handle_error(response) |
||
580 | match = response.json() |
||
581 | return (self.resource.deserialize(match['actionalias']), match['representation']) |
||
582 | |||
583 | |||
584 | class StreamManager(object): |
||
585 | def __init__(self, endpoint, cacert, debug): |
||
586 | self._url = httpclient.get_url_without_trailing_slash(endpoint) + '/stream' |
||
587 | self.debug = debug |
||
588 | self.cacert = cacert |
||
589 | |||
590 | @add_auth_token_to_kwargs_from_env |
||
591 | def listen(self, events=None, **kwargs): |
||
592 | # Late import to avoid very expensive in-direct import (~1 second) when this function is |
||
593 | # not called / used |
||
594 | from sseclient import SSEClient |
||
595 | |||
596 | url = self._url |
||
597 | query_params = {} |
||
598 | |||
599 | if events and isinstance(events, six.string_types): |
||
600 | events = [events] |
||
601 | |||
602 | if 'token' in kwargs: |
||
603 | query_params['x-auth-token'] = kwargs.get('token') |
||
604 | |||
605 | if 'api_key' in kwargs: |
||
606 | query_params['st2-api-key'] = kwargs.get('api_key') |
||
607 | |||
608 | if events: |
||
609 | query_params['events'] = ','.join(events) |
||
610 | |||
611 | query_string = '?' + urllib.parse.urlencode(query_params) |
||
612 | url = url + query_string |
||
613 | |||
614 | for message in SSEClient(url): |
||
615 | |||
616 | # If the execution on the API server takes too long, the message |
||
617 | # can be empty. In this case, rerun the query. |
||
618 | if not message.data: |
||
619 | continue |
||
620 | |||
621 | yield json.loads(message.data) |
||
622 |
It is generally discouraged to redefine built-ins as this makes code very hard to read.