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

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.
@@ -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.9
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"
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