Skip to content

Commit

Permalink
feat: new approach on trying to handle ReadTimeout errors
Browse files Browse the repository at this point in the history
  • Loading branch information
ThiagoPanini committed Sep 12, 2023
1 parent 625d96b commit 4b31d0e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 36 deletions.
19 changes: 14 additions & 5 deletions nbaflow/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from datetime import datetime

from nbaflow.utils.log import log_config
# from nbaflow.utils.requests import handle_timeout_errors
from nbaflow.utils.requests import handle_timeout_errors


# Setting up a logger object
Expand All @@ -43,7 +43,12 @@ class NBAPlayers():
>>> player_info = nba_data.get_players_info(active_players=True)
"""

def __init__(self, request_timeout: int = 30) -> None:
def __init__(
self,
request_timeout: int = 30,
handle_timeout_errors: bool = True,
request_max_tries: int = 5
) -> None:
"""
Initialize the NBAPlayers instance.
Expand All @@ -54,6 +59,8 @@ def __init__(self, request_timeout: int = 30) -> None:
"""

self.request_timeout = request_timeout
self.handle_timeout_errors = handle_timeout_errors
self.request_max_tries = request_max_tries

def get_players_info(self, active_players: bool = True) -> pd.DataFrame:
"""
Expand All @@ -78,9 +85,11 @@ def get_players_info(self, active_players: bool = True) -> pd.DataFrame:
"""

# Getting players information
df_players = commonallplayers.CommonAllPlayers(
timeout=self.request_timeout
).common_all_players.get_data_frame()
df_players = handle_timeout_errors(
endpoint_request=commonallplayers.CommonAllPlayers(
timeout=self.request_timeout
).common_all_players.get_data_frame()
)

# Preparing the DataFrame columns
df_players.columns = [
Expand Down
55 changes: 24 additions & 31 deletions nbaflow/utils/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,70 +18,63 @@
logger = log_config(logger_name=__file__)


# Function that handles timeout erros on requesting data from nba_api
# Function that handles timeout errors on requesting data from nba_api
def handle_timeout_errors(
function,
function_args: dict,
max_attempts: int = 10,
timesleep: int = 3,
timeout_increase: int = 5
endpoint_request,
max_attempts: int = 5,
timesleep: int = 5,
):
"""
Handle timeout errors when requesting data from nba_api.
Args:
function (function):
The function to call for requesting data.
function_args (dict):
A dictionary containing the arguments to be passed to the function.
endpoint_request (Any):
The request to be made using the NBA API endpoint.
max_attempts (int, optional):
The maximum number of attempts to make the request. Defaults to 10.
The maximum number of attempts to make the request. Defaults to 5.
timesleep (int, optional):
The number of seconds to sleep between attempts. Defaults to 3.
timeout_increase (int, optional):
The amount by which to increase the timeout on each attempt.
Defaults to 5.
The number of seconds to sleep between attempts. Defaults to 5.
Returns:
Any: The result returned by the provided function.
Any: The result returned by the provided request.
Raises:
Exception: If an error occurs during the request process.
ReadTimeout: If all attempts to make the request time out.
Note:
This function handles timeout errors (ReadTimeout) that may occur
during the request process. It makes multiple attempts (up to
'max_attempts') with increasing timeouts.
Example:
>>> data = handle_timeout_errors(request_data, {'param1': 'value1',
'param2': 'value2'}, max_attempts=5)
>>> data = handle_timeout_errors(
>>> request_data, max_attempts=5, timesleep=3)
"""

# Looping over a given number of request attempts
for i in range(max_attempts):
try:
# Returning whatever the function was coded to return
return function(**function_args)
return endpoint_request

# Handling timeout errors
except ReadTimeout:
logger.warning(f"Timeout error on requesting data w/ function "
f"{function.__name__}() with the following args "
f"{function_args}. A new attempt will be made with "
f"+{timeout_increase} secs of timeout increase.")
logger.warning("Timeout error on requesting data from nba_api in "
f"the {i + 1}/{max_attempts}. Next attempt will be "
f"made after {timesleep} seconds.")

# Increasing timeout on function args for a new attempt
function_args["timeout"] += timeout_increase
# Sleeping time before next request attempt
sleep(timesleep)

# Another error was thrown and so there is nothing to do
except Exception as e:
logger.error("Error on trying to request data with function "
f"{function.__name__}() with the following args "
f"{function_args}.")
logger.error("A different exception than ReadTimeout was thrown "
"and so this handler function isn't able to deal "
"with it. Check the traceback for more details.")
raise e

# Exceeded max tries
logger.error("Exceeded max tries when trying to request data from nba_api")
raise ReadTimeout

0 comments on commit 4b31d0e

Please sign in to comment.