6565
6666class APIError (Exception ):
6767 def __init__ (self , response , msg = None ):
68- try :
69- response_content = response .content
70- except AttributeError :
71- response_content = response .data
68+ if response is None :
69+ response_content = b''
70+ else :
71+ try :
72+ response_content = response .content
73+ except AttributeError :
74+ response_content = response .data
7275
7376 if response_content != b'' :
7477 if isinstance (response , requests .Response ):
@@ -87,10 +90,13 @@ def __init__(self, response, msg=None):
8790
8891class AuthorizationError (Exception ):
8992 def __init__ (self , response , msg = None ):
90- try :
91- response_content = response .content
92- except AttributeError :
93- response_content = response .data
93+ if response is None :
94+ response_content = b''
95+ else :
96+ try :
97+ response_content = response .content
98+ except AttributeError :
99+ response_content = response .data
94100
95101 if response_content != b'' :
96102 if isinstance (response , requests .Response ):
@@ -1741,24 +1747,30 @@ def _open_data_stream(self, path="/"):
17411747 ready_event .wait (timeout = 10 )
17421748
17431749 def _start_event_loop (self , response , queue , ready_event , update_event ):
1744- client = sseclient .SSEClient (response .iter_content ())
1745- for event in client .events ():
1746- event_type = event .event
1747- if event_type == 'open' or event_type == 'keep-alive' :
1750+ try :
1751+ client = sseclient .SSEClient (response .iter_content ())
1752+ for event in client .events ():
1753+ event_type = event .event
1754+ if event_type == 'open' or event_type == 'keep-alive' :
1755+ pass
1756+ elif event_type == 'put' :
1757+ queue .appendleft (json .loads (event .data ))
1758+ update_event .set ()
1759+ elif event_type == 'auth_revoked' :
1760+ raise AuthorizationError (None ,
1761+ msg = 'Auth token has been revoked' )
1762+ elif event_type == 'error' :
1763+ raise APIError (None , msg = event .data )
1764+
1765+ if not ready_event .is_set ():
1766+ ready_event .set ()
1767+ finally :
1768+ queue .clear ()
1769+ update_event .set ()
1770+ try :
1771+ response .close ()
1772+ except Exception :
17481773 pass
1749- elif event_type == 'put' :
1750- queue .appendleft (json .loads (event .data ))
1751- update_event .set ()
1752- elif event_type == 'auth_revoked' :
1753- raise AuthorizationError (None ,
1754- msg = 'Auth token has been revoked' )
1755- elif event_type == 'error' :
1756- raise APIError (None , msg = event .data )
1757-
1758- if not ready_event .is_set ():
1759- ready_event .set ()
1760- response .close ()
1761- queue .clear ()
17621774
17631775 def _request (self , verb , path = "/" , data = None ):
17641776 url = "%s%s" % (API_URL , path )
@@ -1822,11 +1834,19 @@ def __exit__(self, exc_type, exc_value, traceback):
18221834 def _status (self ):
18231835 self ._queue_lock .acquire ()
18241836 if len (self ._queue ) == 0 or not self ._queue [0 ]:
1825- self ._open_data_stream ("/" )
1837+ try :
1838+ self ._open_data_stream ("/" )
1839+ except AuthorizationError as authorization_error :
1840+ self ._queue_lock .release ()
1841+ raise authorization_error
1842+ except Exception :
1843+ # other error will fall back to pull mode
1844+ pass
18261845 self ._queue_lock .release ()
18271846
1828- value = self ._queue [0 ]['data' ]
1829- if not value :
1847+ value = self ._queue [0 ]['data' ] if len (self ._queue ) > 0 else None
1848+ if value is None :
1849+ # fall back to pull mode
18301850 value = self ._get ("/" )
18311851
18321852 return value
0 commit comments