omnata-plugin-runtime 0.4.8__tar.gz → 0.4.9a106__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.4.8
3
+ Version: 0.4.9a106
4
4
  Summary: Classes and common runtime components for building and running Omnata Plugins
5
5
  Author: James Weakley
6
6
  Author-email: james.weakley@omnata.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "omnata-plugin-runtime"
3
- version = "0.4.8"
3
+ version = "0.4.9-a106"
4
4
  description = "Classes and common runtime components for building and running Omnata Plugins"
5
5
  authors = ["James Weakley <james.weakley@omnata.com>"]
6
6
  readme = "README.md"
@@ -257,7 +257,8 @@ class SyncRequest(ABC):
257
257
  def get_ratelimit_retrying_http_session(self,
258
258
  max_retries: int = 5,
259
259
  backoff_factor: int = 1,
260
- statuses_to_include: List[int] = [429]
260
+ statuses_to_include: List[int] = [429],
261
+ response_time_warning_threshold_ms:Optional[int] = None
261
262
  ):
262
263
  """
263
264
  Returns a requests.Session object which can respond to 429 responses by waiting and retrying.
@@ -272,14 +273,16 @@ class SyncRequest(ABC):
272
273
  max_retries=max_retries,
273
274
  backoff_factor=0,
274
275
  statuses_to_include=statuses_to_include,
275
- respect_retry_after_header=False
276
+ respect_retry_after_header=False,
277
+ response_time_warning_threshold_ms=response_time_warning_threshold_ms
276
278
  )
277
279
  return RateLimitedSession(
278
280
  run_deadline=self._run_deadline,
279
281
  thread_cancellation_token=self._thread_cancellation_token,
280
282
  max_retries=max_retries,
281
283
  backoff_factor=backoff_factor,
282
- statuses_to_include=statuses_to_include
284
+ statuses_to_include=statuses_to_include,
285
+ response_time_warning_threshold_ms=response_time_warning_threshold_ms
283
286
  )
284
287
 
285
288
 
@@ -11,6 +11,7 @@ from logging import getLogger
11
11
  from typing import Any, List, Literal, Optional, Dict, Tuple
12
12
  import requests
13
13
  import time
14
+ import logging
14
15
  from pydantic import Field, root_validator
15
16
  from pydantic.json import pydantic_encoder
16
17
  from .configuration import SubscriptableBaseModel
@@ -386,6 +387,27 @@ class RetryWithLogging(Retry):
386
387
  if self.thread_cancellation_token.wait(backoff):
387
388
  raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting to expire")
388
389
 
390
+ class LongRequestLoggingAdapter(HTTPAdapter):
391
+ """
392
+ An adapter which wraps HTTPAdapter, and logs a warning if a request takes longer than a specified threshold
393
+ """
394
+ def __init__(self,
395
+ threshold_ms:int,
396
+ log_level=logging.WARNING,
397
+ **kwargs):
398
+ super().__init__(**kwargs)
399
+ self.threshold_ms = threshold_ms
400
+ self.logger = logging.getLogger(__name__)
401
+ self.log_level = log_level
402
+
403
+ def send(self, request, *args, **kwargs):
404
+ start_time = time.time()
405
+ response = super().send(request, *args, **kwargs)
406
+ elapsed_time = (time.time() - start_time) * 1000 # Convert to milliseconds
407
+ if elapsed_time > self.threshold_ms:
408
+ self.logger.log(self.log_level, f"Request exceeded response time threshold of {self.threshold_ms}ms, taking {elapsed_time:.2f}ms to respond. URL: {request.url}")
409
+ return response
410
+
389
411
 
390
412
  class RateLimitedSession(requests.Session):
391
413
  """
@@ -400,7 +422,8 @@ class RateLimitedSession(requests.Session):
400
422
  max_retries=5,
401
423
  backoff_factor=1,
402
424
  statuses_to_include:List[int] = [429],
403
- respect_retry_after_header:bool = True):
425
+ respect_retry_after_header:bool = True,
426
+ response_time_warning_threshold_ms:Optional[int] = None):
404
427
  super().__init__()
405
428
  self.max_retries = max_retries
406
429
  self.backoff_factor = backoff_factor
@@ -418,7 +441,10 @@ class RateLimitedSession(requests.Session):
418
441
  respect_retry_after_header=respect_retry_after_header
419
442
  )
420
443
  retry_strategy.thread_cancellation_token = thread_cancellation_token
421
- adapter = HTTPAdapter(max_retries=retry_strategy)
444
+ if response_time_warning_threshold_ms is not None:
445
+ adapter = LongRequestLoggingAdapter(max_retries=retry_strategy, threshold_ms=response_time_warning_threshold_ms)
446
+ else:
447
+ adapter = HTTPAdapter(max_retries=retry_strategy)
422
448
  self.mount("https://", adapter)
423
449
  self.mount("http://", adapter)
424
450