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/__init__.py +38 -38
- pytrms/_base/__init__.py +24 -24
- pytrms/_base/ioniclient.py +32 -32
- pytrms/_base/mqttclient.py +119 -119
- pytrms/_version.py +26 -26
- pytrms/clients/__init__.py +33 -33
- pytrms/clients/db_api.py +200 -183
- pytrms/clients/ioniclient.py +87 -87
- pytrms/clients/modbus.py +532 -528
- pytrms/clients/mqtt.py +800 -797
- pytrms/clients/ssevent.py +82 -82
- pytrms/compose/__init__.py +2 -2
- pytrms/compose/composition.py +302 -302
- pytrms/data/IoniTofPrefs.ini +112 -112
- pytrms/data/ParaIDs.csv +731 -731
- pytrms/helpers.py +126 -120
- pytrms/instrument.py +119 -119
- pytrms/measurement.py +173 -173
- pytrms/peaktable.py +499 -501
- pytrms/plotting/__init__.py +4 -4
- pytrms/plotting/plotting.py +27 -27
- pytrms/readers/__init__.py +4 -4
- pytrms/readers/ionitof_reader.py +472 -472
- {pytrms-0.9.2.dist-info → pytrms-0.9.3.dist-info}/LICENSE +339 -339
- {pytrms-0.9.2.dist-info → pytrms-0.9.3.dist-info}/METADATA +3 -2
- pytrms-0.9.3.dist-info/RECORD +27 -0
- {pytrms-0.9.2.dist-info → pytrms-0.9.3.dist-info}/WHEEL +1 -1
- pytrms-0.9.2.dist-info/RECORD +0 -27
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
|
+
|
pytrms/compose/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .composition import *
|
|
2
|
-
|
|
1
|
+
from .composition import *
|
|
2
|
+
|