Scheduling
wingpy.scheduling
¶
Most API interaction can be optimized by utilizing conrurency while also adapting to rate limits. This module provides a set of classes to handle asynchronous tasks and request throttling and in way makes sure that the API is not overloaded with requests while also reaching maximum performance.
RequestLogEntry
dataclass
¶
RequestThrottler
¶
RequestThrottler(
*,
backoff_initial: float = 1.0,
backoff_multiplier: float = 2.0,
rate_limit_period: float = 0.0,
rate_limit_max_requests: int = 0
)
Handle request throttling for API calls through exponential backoff and adjusting to rate limiting.
Source code in src/wingpy/scheduling.py
backoff_initial
instance-attribute
¶
The initial delay for exponential backoff.
backoff_multiplier
instance-attribute
¶
The multiplier for exponential backoff.
rate_limit_max_requests
instance-attribute
¶
The maximum number of requests allowed in the rate limit period.
rate_limit_period
instance-attribute
¶
The period for rate limiting in seconds.
calculate_delay_from_backoff
¶
Calculate a delay based on exponential backoff. This method uses the backoff_initial and backoff_multiplier attributes to determine the delay.
Returns:
Type | Description |
---|---|
float
|
The calculated delay in seconds. |
Source code in src/wingpy/scheduling.py
calculate_delay_from_header
¶
Calculate the delay based on the Retry-After header.
Two different valid formats exists: Retry-After: <delay-seconds>
and Retry-After: <http-date>
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
Arrow
|
Due to multiple threads, the start time is passed as a parameter to ensure that the delay is calculated from the point in time where the the request was sent. |
required |
retry_after
|
str
|
The value of the Retry-After header from an HTTP response. |
required |
Returns:
Type | Description |
---|---|
float
|
The calculated delay in seconds. |
Source code in src/wingpy/scheduling.py
calculate_delay_from_period
¶
Based on the current run rate and the platform rate limit parameters, calculate a reasonable delay. Usefull when the API does not provide a Retry-After header but the rate limit period is known. If just a few requests where made in the rate limit period and we did not cause the rate limiting, we can calculate a delay based on the number of successful requests.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request_log
|
list[RequestLogEntry]
|
A list of request log entries leading up to the rate limit response. Used to calculate the run rate and oldest request timestamp. |
required |
Returns:
Type | Description |
---|---|
float
|
The calculated delay in seconds. |
Source code in src/wingpy/scheduling.py
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
|
calculate_delay_from_rate_limit
¶
calculate_delay_from_rate_limit(
*,
start_time: Arrow,
response: Response,
request_log: list[RequestLogEntry]
) -> float
Calculate a delay based on server rate limiting.
This method checks for the Retry-After header in the response and calculates the delay accordingly. If the header is not present, it uses the platform-specific rate limit values to determine the delay. If neither is available, it falls back to exponential backoff.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
Arrow
|
Due to multiple threads, the start time is passed as a parameter to ensure that the delay is calculated from the point in time where the the request was sent. |
required |
response
|
Response
|
The HTTP response object from the API call. Used to check for the Retry-After header. |
required |
request_log
|
list[RequestLogEntry]
|
A list of request log entries leading up to the rate limit response. Used to calculate the run rate and oldest request timestamp in case the Retry-After header is not present. |
required |
Returns:
Type | Description |
---|---|
float
|
The calculated delay in seconds. |
Source code in src/wingpy/scheduling.py
ensure_delay
¶
Sleeps until the time has passed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
Arrow
|
Start timestamp of the delay period. |
required |
delay
|
float | int
|
The delay in seconds to sleep before continuing. |
required |
Source code in src/wingpy/scheduling.py
reset_backoff
¶
Reset the current backoff delay to 0. Usefull when the API is not longer rate limiting.
run_rate
¶
Calculate the current run rate and oldest request timestamp. This is a placeholder implementation and should be replaced with actual logic.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request_log
|
list[RequestLogEntry]
|
A list of request log entries leading up to the rate limit response. Used to calculate the run rate and oldest request timestamp. |
required |
Returns:
Type | Description |
---|---|
tuple[int, Arrow | None]
|
A tuple containing the number of requests in the rate limit period and the timestamp of the oldest request in the rate limit period. |
Source code in src/wingpy/scheduling.py
wait_for_backoff
¶
Returns after waiting for the exponential backoff timer.
Usefull when the API does not provide a Retry-After header and the rate limit period of the API is not known.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
Arrow
|
Due to multiple threads, the start time is passed as a parameter to ensure that the delay is calculated from the point in time where the the request was sent. |
required |
Source code in src/wingpy/scheduling.py
wait_for_rate_limit
¶
wait_for_rate_limit(
*,
start_time: Arrow,
response: Response,
request_log: list[RequestLogEntry]
) -> None
Returns after waiting for the rate limit timer.
Usefull when the API provides a Retry-After header or when the rate limit period is known.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
Arrow
|
Due to multiple threads, the start time is passed as a parameter to ensure that the delay is calculated from the point in time where the the request was sent. |
required |
response
|
Response
|
Response object from the API call with HTTP status code 429 (Too Many Requests). |
required |
request_log
|
list[RequestLogEntry]
|
A list of request log entries leading up to the rate limit response. |
required |
Source code in src/wingpy/scheduling.py
TaskRunner
¶
Manage and execute asynchronous tasks using a thread pool executor with a specified number of worker threads.
Source code in src/wingpy/scheduling.py
loop
instance-attribute
¶
The event loop used to manage asynchronous tasks.
max_workers
instance-attribute
¶
The maximum number of worker threads to use in the thread pool.
run
¶
Run all scheduled tasks and return their results.
Returns:
Type | Description |
---|---|
dict[str, Any]
|
A dictionary where each key is the name of a task and the value is the result of that task. |
Source code in src/wingpy/scheduling.py
schedule
¶
schedule(
func: Callable[P, R],
*args: args,
_task_name: str | None = None,
**kwargs: kwargs
) -> None
Schedule a function to be run asynchronously.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func
|
Callable[P, R]
|
The function to be executed. |
required |
_task_name
|
str | None
|
Optional name for the task. If not provided, a name will be
generated, similar to |
None
|
*args
|
args
|
Positional arguments to pass to the function. |
()
|
**kwargs
|
kwargs
|
Keyword arguments to pass to the function. |
{}
|