pytrms 0.9.2__py3-none-any.whl → 0.9.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pytrms/clients/ssevent.py CHANGED
@@ -1,82 +1,82 @@
1
- import re
2
- from collections import namedtuple
3
- from collections.abc import Iterable
4
-
5
- import requests
6
-
7
- from . import _logging
8
-
9
- log = _logging.getLogger(__name__)
10
-
11
- _event_rv = namedtuple('ssevent', ['event', 'data'])
12
-
13
- class SSEventListener(Iterable):
14
-
15
- @staticmethod
16
- def _line_stream(response):
17
- # Note: using .iter_content() seems to yield results faster than .iter_lines()
18
- line = ''
19
- for bite in response.iter_content(chunk_size=1, decode_unicode=True):
20
- line += bite
21
- if bite == '\n':
22
- yield line.strip()
23
- line = ''
24
-
25
- def __init__(self, event_re=None, host_url='http://127.0.0.1:5066',
26
- endpoint='/api/events', session=None):
27
- self.uri = host_url + endpoint
28
- if session is not None:
29
- self._get = session.get
30
- else:
31
- self._get = requests.get
32
- self._connect_response = None
33
- self.subscriptions = set()
34
- if event_re is not None:
35
- self.subscribe(event_re)
36
-
37
- def subscribe(self, event_re):
38
- """Listen for events matching the given string or regular expression."""
39
- self.subscriptions.add(re.compile(event_re))
40
- if self._connect_response is None:
41
- r = self._get(self.uri, headers={'accept': 'text/event-stream'}, stream=True)
42
- if not r.ok:
43
- log.error(f"no connection to {self.uri} (got [{r.status_code}])")
44
- r.raise_for_status()
45
-
46
- self._connect_response = r
47
-
48
- def unsubscribe(self, event_re):
49
- """Stop listening for certain events."""
50
- self.subscriptions.remove(re.compile(event_re))
51
- if not len(self.subscriptions):
52
- log.debug(f"closing connection to {self.uri}")
53
- self._connect_response.close()
54
- self._connect_response = None
55
-
56
- def __iter__(self):
57
- if self._connect_response is None:
58
- raise Exception("call .subscribe() first to listen for events")
59
-
60
- event = msg = ''
61
- for line in self._line_stream(self._connect_response): # blocks...
62
- if not line:
63
- # an empty line concludes an event
64
- if event and any(re.match(sub, event) for sub in self.subscriptions):
65
- yield _event_rv(event, msg)
66
-
67
- # Note: any further empty lines are ignored (may be used as keep-alive),
68
- # but in either case clear event and msg to rearm for the next event:
69
- event = msg = ''
70
- continue
71
-
72
- key, val = line.split(':', maxsplit=1)
73
- if not key:
74
- # this is a comment, starting with a colon ':' ...
75
- log.log(_logging.TRACE, "sse:" + val)
76
- elif key == 'event':
77
- event = val.lstrip()
78
- elif key == 'data':
79
- msg += val.lstrip()
80
- else:
81
- log.warning(f"unknown SSE-key <{key}> in stream")
82
-
1
+ import re
2
+ from collections import namedtuple
3
+ from collections.abc import Iterable
4
+
5
+ import requests
6
+
7
+ from . import _logging
8
+
9
+ log = _logging.getLogger(__name__)
10
+
11
+ _event_rv = namedtuple('ssevent', ['event', 'data'])
12
+
13
+ class SSEventListener(Iterable):
14
+
15
+ @staticmethod
16
+ def _line_stream(response):
17
+ # Note: using .iter_content() seems to yield results faster than .iter_lines()
18
+ line = ''
19
+ for bite in response.iter_content(chunk_size=1, decode_unicode=True):
20
+ line += bite
21
+ if bite == '\n':
22
+ yield line.strip()
23
+ line = ''
24
+
25
+ def __init__(self, event_re=None, host_url='http://127.0.0.1:5066',
26
+ endpoint='/api/events', session=None):
27
+ self.uri = host_url + endpoint
28
+ if session is not None:
29
+ self._get = session.get
30
+ else:
31
+ self._get = requests.get
32
+ self._connect_response = None
33
+ self.subscriptions = set()
34
+ if event_re is not None:
35
+ self.subscribe(event_re)
36
+
37
+ def subscribe(self, event_re):
38
+ """Listen for events matching the given string or regular expression."""
39
+ self.subscriptions.add(re.compile(event_re))
40
+ if self._connect_response is None:
41
+ r = self._get(self.uri, headers={'accept': 'text/event-stream'}, stream=True)
42
+ if not r.ok:
43
+ log.error(f"no connection to {self.uri} (got [{r.status_code}])")
44
+ r.raise_for_status()
45
+
46
+ self._connect_response = r
47
+
48
+ def unsubscribe(self, event_re):
49
+ """Stop listening for certain events."""
50
+ self.subscriptions.remove(re.compile(event_re))
51
+ if not len(self.subscriptions):
52
+ log.debug(f"closing connection to {self.uri}")
53
+ self._connect_response.close()
54
+ self._connect_response = None
55
+
56
+ def __iter__(self):
57
+ if self._connect_response is None:
58
+ raise Exception("call .subscribe() first to listen for events")
59
+
60
+ event = msg = ''
61
+ for line in self._line_stream(self._connect_response): # blocks...
62
+ if not line:
63
+ # an empty line concludes an event
64
+ if event and any(re.match(sub, event) for sub in self.subscriptions):
65
+ yield _event_rv(event, msg)
66
+
67
+ # Note: any further empty lines are ignored (may be used as keep-alive),
68
+ # but in either case clear event and msg to rearm for the next event:
69
+ event = msg = ''
70
+ continue
71
+
72
+ key, val = line.split(':', maxsplit=1)
73
+ if not key:
74
+ # this is a comment, starting with a colon ':' ...
75
+ log.log(_logging.TRACE, "sse:" + val)
76
+ elif key == 'event':
77
+ event = val.lstrip()
78
+ elif key == 'data':
79
+ msg += val.lstrip()
80
+ else:
81
+ log.warning(f"unknown SSE-key <{key}> in stream")
82
+
@@ -1,2 +1,2 @@
1
- from .composition import *
2
-
1
+ from .composition import *
2
+