Retrying in the face of limitsยค
Grand Challenge has several limits in place to ensure fair use and system reliability.
One such limit you could run into is the maximum number of uploads. Uploads are temporarily stored before being processed in the background and automatically cleaned up afterward. If you hit the limit during a function call (e.g. add_case_to_archive) the uploads will remain unassigned. These uploads will eventually be cleaned up automatically, but can temporarily block creating any new uploads until that happens. If you retry the function call before enough uploads have been cleaned up, you might unintentionally be blocking yourself by creating yet more unassigned uploads.
The upload limit being reached is generally reported by a 400-coded response from Grand Challenge which will tell you:
"You have created too many uploads. Please try again later."
One solution could be to use a retry strategy to catch these responses, wait for a while, and continue from where your program initially ran into these limits.
Whether this strategy fits your specific use case is up to you.
The following example strategy would retry after 5 minutes: a similar construct would work for other limit-related responses.
Example
import httpx
import gcapi
class UploadRetryStrategy(gcapi.retries.SelectiveBackoffStrategy):
"""Retry strategy that handles upload limits specifically.
In addition to the standard retryable errors handled by
SelectiveBackoffStrategy, this strategy also retries on
BAD_REQUEST responses that indicate the user has created too many
uploads.
"""
def __init__(self):
super().__init__(
backoff_factor=0.1,
maximum_number_of_retries=5, # Applies to other retriable errors
)
def get_delay(self, latest_response):
delay = None # Do not retry at all, by default
if latest_response.status_code == httpx.codes.BAD_REQUEST:
response_json = latest_response.json()
non_field_errors = response_json.get("non_field_errors", [])
if (
len(non_field_errors) == 1
and "you have created too many uploads"
in non_field_errors[0].casefold()
):
print("Retrying upload due to too many uploads.")
delay = 300 # Delay for 5 minutes
return delay
You can use it by passing it to the Client when initializing it: