Skip to content

Commit bc59764

Browse files
committed
Fix ld_eventsource
1 parent 2336816 commit bc59764

17 files changed

+265
-199
lines changed

ld_eventsource/actions.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ class Event(Action):
1717
Instances of this class are returned by both :attr:`.SSEClient.events` and
1818
:attr:`.SSEClient.all`.
1919
"""
20-
def __init__(self,
21-
event: str='message',
22-
data: str='',
23-
id: Optional[str]=None,
24-
last_event_id: Optional[str]=None
20+
21+
def __init__(
22+
self,
23+
event: str = 'message',
24+
data: str = '',
25+
id: Optional[str] = None,
26+
last_event_id: Optional[str] = None,
2527
):
2628
self._event = event
2729
self._data = data
@@ -59,8 +61,12 @@ def last_event_id(self) -> Optional[str]:
5961
def __eq__(self, other):
6062
if not isinstance(other, Event):
6163
return False
62-
return self._event == other._event and self._data == other._data \
63-
and self._id == other._id and self.last_event_id == other.last_event_id
64+
return (
65+
self._event == other._event
66+
and self._data == other._data
67+
and self._id == other._id
68+
and self.last_event_id == other.last_event_id
69+
)
6470

6571
def __repr__(self):
6672
return "Event(event=\"%s\", data=%s, id=%s, last_event_id=%s)" % (

ld_eventsource/config/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from .connect_strategy import ConnectionClient, ConnectionResult, ConnectStrategy
1+
from .connect_strategy import (ConnectionClient, ConnectionResult,
2+
ConnectStrategy)
23
from .error_strategy import ErrorStrategy
34
from .retry_delay_strategy import RetryDelayStrategy

ld_eventsource/config/connect_strategy.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ def create_client(self, logger: Logger) -> ConnectionClient:
3535
@staticmethod
3636
def http(
3737
url: str,
38-
headers: Optional[dict]=None,
39-
pool: Optional[PoolManager]=None,
40-
urllib3_request_options: Optional[dict]=None
38+
headers: Optional[dict] = None,
39+
pool: Optional[PoolManager] = None,
40+
urllib3_request_options: Optional[dict] = None,
4141
) -> ConnectStrategy:
4242
"""
4343
Creates the default HTTP implementation, specifying request parameters.
@@ -48,7 +48,9 @@ def http(
4848
:param urllib3_request_options: optional ``kwargs`` to add to the ``request`` call; these
4949
can include any parameters supported by ``urllib3``, such as ``timeout``
5050
"""
51-
return _HttpConnectStrategy(_HttpConnectParams(url, headers, pool, urllib3_request_options))
51+
return _HttpConnectStrategy(
52+
_HttpConnectParams(url, headers, pool, urllib3_request_options)
53+
)
5254

5355

5456
class ConnectionClient:
@@ -67,7 +69,9 @@ def connect(self, last_event_id: Optional[str]) -> ConnectionResult:
6769
(should be sent to the server to support resuming an interrupted stream)
6870
:return: a :class:`ConnectionResult` representing the stream
6971
"""
70-
raise NotImplementedError("ConnectionClient base class cannot be used by itself")
72+
raise NotImplementedError(
73+
"ConnectionClient base class cannot be used by itself"
74+
)
7175

7276
def close(self):
7377
"""
@@ -82,16 +86,12 @@ def __exit__(self, type, value, traceback):
8286
self.close()
8387

8488

85-
8689
class ConnectionResult:
8790
"""
8891
The return type of :meth:`ConnectionClient.connect()`.
8992
"""
90-
def __init__(
91-
self,
92-
stream: Iterator[bytes],
93-
closer: Optional[Callable]
94-
):
93+
94+
def __init__(self, stream: Iterator[bytes], closer: Optional[Callable]):
9595
self.__stream = stream
9696
self.__closer = closer
9797

ld_eventsource/config/error_strategy.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ def continue_with_time_limit(max_time: float) -> ErrorStrategy:
8686
return _TimeLimitErrorStrategy(max_time, 0)
8787

8888
@staticmethod
89-
def from_lambda(fn: Callable[[Optional[Exception]], Tuple[bool, Optional[ErrorStrategy]]]) -> ErrorStrategy:
89+
def from_lambda(
90+
fn: Callable[[Optional[Exception]], Tuple[bool, Optional[ErrorStrategy]]]
91+
) -> ErrorStrategy:
9092
"""
9193
Convenience method for creating an ErrorStrategy whose ``apply`` method is equivalent to
9294
the given lambda.
@@ -98,7 +100,9 @@ def from_lambda(fn: Callable[[Optional[Exception]], Tuple[bool, Optional[ErrorSt
98100

99101

100102
class _LambdaErrorStrategy(ErrorStrategy):
101-
def __init__(self, fn: Callable[[Optional[Exception]], Tuple[bool, Optional[ErrorStrategy]]]):
103+
def __init__(
104+
self, fn: Callable[[Optional[Exception]], Tuple[bool, Optional[ErrorStrategy]]]
105+
):
102106
self.__fn = fn
103107

104108
def apply(self, exception: Optional[Exception]) -> Tuple[bool, ErrorStrategy]:
@@ -114,7 +118,10 @@ def __init__(self, max_attempts: int, counter: int):
114118
def apply(self, exception: Optional[Exception]) -> Tuple[bool, ErrorStrategy]:
115119
if self.__counter >= self.__max_attempts:
116120
return (ErrorStrategy.FAIL, self)
117-
return (ErrorStrategy.CONTINUE, _MaxAttemptsErrorStrategy(self.__max_attempts, self.__counter + 1))
121+
return (
122+
ErrorStrategy.CONTINUE,
123+
_MaxAttemptsErrorStrategy(self.__max_attempts, self.__counter + 1),
124+
)
118125

119126

120127
class _TimeLimitErrorStrategy(ErrorStrategy):
@@ -124,7 +131,10 @@ def __init__(self, max_time: float, start_time: float):
124131

125132
def apply(self, exception: Optional[Exception]) -> Tuple[bool, ErrorStrategy]:
126133
if self.__start_time == 0:
127-
return (ErrorStrategy.CONTINUE, _TimeLimitErrorStrategy(self.__max_time, time.time()))
134+
return (
135+
ErrorStrategy.CONTINUE,
136+
_TimeLimitErrorStrategy(self.__max_time, time.time()),
137+
)
128138
if (time.time() - self.__start_time) < self.__max_time:
129139
return (ErrorStrategy.CONTINUE, self)
130140
return (ErrorStrategy.FAIL, self)

ld_eventsource/config/retry_delay_strategy.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def apply(self, base_delay: float) -> Tuple[float, RetryDelayStrategy]:
3434
def default(
3535
max_delay: Optional[float] = None,
3636
backoff_multiplier: float = 2,
37-
jitter_multiplier: Optional[float] = None
37+
jitter_multiplier: Optional[float] = None,
3838
) -> RetryDelayStrategy:
3939
"""
4040
Provides the default retry delay behavior for :class:`.SSEClient`, which includes
@@ -59,11 +59,18 @@ def default(
5959
:param jitter_multiplier: a fraction from 0.0 to 1.0 for how much of the delay may be
6060
pseudo-randomly subtracted
6161
"""
62-
return _DefaultRetryDelayStrategy(max_delay or 0, backoff_multiplier, jitter_multiplier or 0,
63-
0, _ReusableRandom(time.time()))
62+
return _DefaultRetryDelayStrategy(
63+
max_delay or 0,
64+
backoff_multiplier,
65+
jitter_multiplier or 0,
66+
0,
67+
_ReusableRandom(time.time()),
68+
)
6469

6570
@staticmethod
66-
def from_lambda(fn: Callable[[float], Tuple[float, Optional[RetryDelayStrategy]]]) -> RetryDelayStrategy:
71+
def from_lambda(
72+
fn: Callable[[float], Tuple[float, Optional[RetryDelayStrategy]]]
73+
) -> RetryDelayStrategy:
6774
"""
6875
Convenience method for creating a RetryDelayStrategy whose ``apply`` method is equivalent to
6976
the given lambda.
@@ -81,7 +88,7 @@ def __init__(
8188
backoff_multiplier: float,
8289
jitter_multiplier: float,
8390
last_base_delay: float,
84-
random: _ReusableRandom
91+
random: _ReusableRandom,
8592
):
8693
self.__max_delay = max_delay
8794
self.__backoff_multiplier = backoff_multiplier
@@ -90,8 +97,11 @@ def __init__(
9097
self.__random = random
9198

9299
def apply(self, base_delay: float) -> Tuple[float, RetryDelayStrategy]:
93-
next_base_delay = base_delay if self.__last_base_delay == 0 else \
94-
self.__last_base_delay * self.__backoff_multiplier
100+
next_base_delay = (
101+
base_delay
102+
if self.__last_base_delay == 0
103+
else self.__last_base_delay * self.__backoff_multiplier
104+
)
95105
if self.__max_delay > 0 and next_base_delay > self.__max_delay:
96106
next_base_delay = self.__max_delay
97107
adjusted_delay = next_base_delay
@@ -101,19 +111,24 @@ def apply(self, base_delay: float) -> Tuple[float, RetryDelayStrategy]:
101111
# To avoid having this object contain mutable state, we create a new Random with the same
102112
# state as our previous Random before using it.
103113
random = random.clone()
104-
adjusted_delay -= (random.random() * self.__jitter_multiplier * adjusted_delay)
114+
adjusted_delay -= (
115+
random.random() * self.__jitter_multiplier * adjusted_delay
116+
)
105117

106118
next_strategy = _DefaultRetryDelayStrategy(
107119
self.__max_delay,
108120
self.__backoff_multiplier,
109121
self.__jitter_multiplier,
110122
next_base_delay,
111-
random
123+
random,
112124
)
113125
return (adjusted_delay, next_strategy)
114126

127+
115128
class _LambdaRetryDelayStrategy(RetryDelayStrategy):
116-
def __init__(self, fn: Callable[[float], Tuple[float, Optional[RetryDelayStrategy]]]):
129+
def __init__(
130+
self, fn: Callable[[float], Tuple[float, Optional[RetryDelayStrategy]]]
131+
):
117132
self.__fn = fn
118133

119134
def apply(self, base_delay: float) -> Tuple[float, RetryDelayStrategy]:

ld_eventsource/http.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ class _HttpConnectParams:
1414
def __init__(
1515
self,
1616
url: str,
17-
headers: Optional[dict]=None,
18-
pool: Optional[PoolManager]=None,
19-
urllib3_request_options: Optional[dict]=None
17+
headers: Optional[dict] = None,
18+
pool: Optional[PoolManager] = None,
19+
urllib3_request_options: Optional[dict] = None,
2020
):
2121
self.__url = url
2222
self.__headers = headers
@@ -57,24 +57,33 @@ def connect(self, last_event_id: Optional[str]) -> Tuple[Iterator[bytes], Callab
5757
if last_event_id:
5858
headers['Last-Event-ID'] = last_event_id
5959

60-
request_options = self.__params.urllib3_request_options.copy() if self.__params.urllib3_request_options else {}
60+
request_options = (
61+
self.__params.urllib3_request_options.copy()
62+
if self.__params.urllib3_request_options
63+
else {}
64+
)
6165
request_options['headers'] = headers
6266

6367
try:
6468
resp = self.__pool.request(
6569
'GET',
6670
self.__params.url,
6771
preload_content=False,
68-
retries=Retry(total=None, read=0, connect=0, status=0, other=0, redirect=3),
69-
**request_options)
72+
retries=Retry(
73+
total=None, read=0, connect=0, status=0, other=0, redirect=3
74+
),
75+
**request_options
76+
)
7077
except MaxRetryError as e:
7178
reason: Optional[Exception] = e.reason
7279
if reason is not None:
73-
raise reason # e.reason is the underlying I/O error
80+
raise reason # e.reason is the underlying I/O error
7481
if resp.status >= 400 or resp.status == 204:
7582
raise HTTPStatusError(resp.status)
7683
content_type = resp.headers.get('Content-Type', None)
77-
if content_type is None or not str(content_type).startswith("text/event-stream"):
84+
if content_type is None or not str(content_type).startswith(
85+
"text/event-stream"
86+
):
7887
raise HTTPContentTypeError(content_type or '')
7988

8089
stream = resp.stream(_CHUNK_SIZE)

ld_eventsource/reader.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ def __init__(
5656
self,
5757
lines_source: Iterable[str],
5858
last_event_id: Optional[str] = None,
59-
set_retry: Optional[Callable[[int], None]] = None
60-
):
59+
set_retry: Optional[Callable[[int], None]] = None,
60+
):
6161
self._lines_source = lines_source
6262
self._last_event_id = last_event_id
6363
self._set_retry = set_retry
@@ -80,7 +80,7 @@ def events_and_comments(self):
8080
"message" if event_type == "" else event_type,
8181
event_data,
8282
event_id,
83-
self._last_event_id
83+
self._last_event_id,
8484
)
8585
event_type = ""
8686
event_data = None
@@ -97,11 +97,13 @@ def events_and_comments(self):
9797
name = line[:colon_pos]
9898
if colon_pos < (len(line) - 1) and line[colon_pos + 1] == ' ':
9999
colon_pos += 1
100-
value = line[colon_pos+1:]
100+
value = line[colon_pos + 1:]
101101
if name == 'event':
102102
event_type = value
103103
elif name == 'data':
104-
event_data = value if event_data is None else (event_data + "\n" + value)
104+
event_data = (
105+
value if event_data is None else (event_data + "\n" + value)
106+
)
105107
elif name == 'id':
106108
if value.find("\x00") < 0:
107109
event_id = value

0 commit comments

Comments
 (0)