Skip to content

Commit 05a0c6d

Browse files
authored
Merge pull request #166 from intezer/feat/rate-limit-submit-alerts
refactor(errors): better rate limit management in AnalysisRateLimitError
2 parents 6b83f52 + f4e0431 commit 05a0c6d

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

CHANGES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
1.24.1
2+
-------
3+
- Rate limit exception improvements
4+
15
1.24.0
26
-------
37
- Introduce File class

intezer_sdk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.24.0'
1+
__version__ = '1.24.1'

intezer_sdk/errors.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from typing import Optional
2-
2+
import datetime
33
import requests
44

55

@@ -151,9 +151,7 @@ def __init__(self, response: requests.Response):
151151

152152
class AlertInProgressError(AlertError):
153153
def __init__(self, alert_id: str):
154-
super().__init__(
155-
f'The alert {alert_id} is being processed at the moment, please try again later'
156-
)
154+
super().__init__(f'The alert {alert_id} is being processed at the moment, please try again later')
157155

158156

159157
class AlertNotFoundError(AlertError):
@@ -182,12 +180,33 @@ def __init__(self, response: requests.Response):
182180

183181

184182
class AnalysisRateLimitError(ServerError):
185-
def __init__(self, response: requests.Response):
186-
super().__init__('Analysis rate limit reached', response)
187-
self.limit = response.headers.get('X-RateLimit-Limit')
188-
self.remaining = response.headers.get('X-RateLimit-Remaining')
189-
self.reset_time_in_sec = response.headers.get('X-RateLimit-Reset')
190-
self.retry_after = response.headers.get('Retry-After')
183+
def __init__(self, response: requests.Response, message: str = 'Analysis rate limit reached'):
184+
super().__init__(message, response)
185+
186+
self.limit: Optional[int] = self._parse_header(response.headers, 'X-RateLimit-Limit', int)
187+
self.remaining: Optional[int] = self._parse_header(response.headers, 'X-RateLimit-Remaining', int)
188+
self.reset_time_in_sec: Optional[float] = self._parse_header(response.headers, 'X-RateLimit-Reset', float)
189+
self.retry_after: Optional[float] = self._parse_header(response.headers, 'Retry-After', float)
190+
191+
now = datetime.datetime.utcnow().timestamp()
192+
if self.retry_after is not None:
193+
remaining_time = self.retry_after
194+
elif self.reset_time_in_sec is not None:
195+
remaining_time = max(1.0, self.reset_time_in_sec - now)
196+
else:
197+
remaining_time = None
198+
199+
self.rate_limit_remaining_time_in_seconds = remaining_time
200+
201+
@staticmethod
202+
def _parse_header(headers, name: str, cast_type):
203+
value = headers.get(name)
204+
if not value:
205+
return None
206+
try:
207+
return cast_type(value)
208+
except (ValueError, TypeError):
209+
return value
191210

192211

193212
class IncidentNotFoundError(IntezerError):

0 commit comments

Comments
 (0)