def check_resource(resource, get_method=None, query_string='', wait_time=1, retries=None, raise_on_error=False, api=None): """Waits until a resource is finished. Given a resource and its corresponding get_method (if absent, the generic get_resource is used), it calls the get_method on the resource with the given query_string and waits with sleeping intervals of wait_time until the resource is in a final state (either FINISHED or FAULTY. The number of retries can be limited using the retries parameter. """ if isinstance(resource, basestring): resource_id = resource else: resource_id = get_resource_id(resource) resource_id = get_resource_id(resource) if resource_id is None: raise ValueError("Failed to extract a valid resource id to check.") kwargs = {'query_string': query_string} if get_method is None and hasattr(api, 'get_resource'): get_method = api.get_resource elif get_method is None: raise ValueError("You must supply either the get_method or the api" " connection info to retrieve the resource") if isinstance(resource, basestring): resource = get_method(resource, **kwargs) counter = 0 while retries is None or counter < retries: counter += 1 status = get_status(resource) code = status['code'] if code == c.FINISHED: if counter > 1: # final get call to retrieve complete resource resource = get_method(resource, **kwargs) if raise_on_error: exception_on_error(resource) return resource elif code == c.FAULTY: raise ValueError(status) time.sleep(get_exponential_wait(wait_time, counter)) # retries for the finished status use a query string that gets the # minimal available resource if kwargs.get('query_string') is not None: tiny_kwargs = {'query_string': c.TINY_RESOURCE} else: tiny_kwargs = {} resource = get_method(resource, **tiny_kwargs) if raise_on_error: exception_on_error(resource) return resource
def resource_is_ready(resource): """Checks a fully fledged resource structure and returns True if finished. """ if not isinstance(resource, dict): raise Exception("No valid resource structure found") # full resources if 'object' in resource: if 'error' not in resource: raise Exception("No valid resource structure found") if resource['error'] is not None: raise Exception(resource['error']['status']['message']) return (resource['code'] in [HTTP_OK, HTTP_ACCEPTED] and get_status(resource)['code'] == c.FINISHED) # only API response contents return get_status(resource)['code'] == c.FINISHED
def resource_is_ready(resource): """Checks a fully fledged resource structure and returns True if finished. """ if not isinstance(resource, dict) or 'error' not in resource: raise Exception("No valid resource structure found") if resource['error'] is not None: raise Exception(resource['error']['status']['message']) return (resource['code'] in [HTTP_OK, HTTP_ACCEPTED] and get_status(resource)['code'] == c.FINISHED)
def check_resource(resource, get_method=None, query_string='', wait_time=1, retries=None, raise_on_error=False, max_elapsed_estimate=float('inf'), api=None, debug=False): """Waits until a resource is finished. Given a resource and its corresponding get_method (if absent, the generic get_resource is used), it calls the get_method on the resource with the given query_string and waits with sleeping intervals of wait_time until the resource is in a final state (either FINISHED or FAULTY. The number of retries can be limited using the retries parameter. """ resource_id = get_resource_id(resource) # ephemeral predictions if isinstance(resource, dict) and resource.get("resource") is None: return resource if resource_id is None: raise ValueError("Failed to extract a valid resource id to check.") if wait_time <= 0: raise ValueError("The time to wait needs to be positive.") debug = debug or (api is not None and (api.debug or api.short_debug)) if debug: print("Checking resource: %s" % resource_id) kwargs = {'query_string': query_string} if get_method is None and hasattr(api, 'get_resource'): get_method = api.get_resource elif get_method is None: raise ValueError("You must supply either the get_method or the api" " connection info to retrieve the resource") if isinstance(resource, str): if debug: print("Getting resource %s" % resource_id) resource = get_method(resource_id, **kwargs) counter = 0 elapsed = 0 while retries is None or counter < retries: counter += 1 status = get_status(resource) code = status['code'] if debug: print("The resource has status code: %s" % code) if code == c.FINISHED: if counter > 1: if debug: print("Getting resource %s with args %s" % (resource_id, kwargs)) # final get call to retrieve complete resource resource = get_method(resource, **kwargs) if raise_on_error: exception_on_error(resource) return resource if code == c.FAULTY: if raise_on_error: exception_on_error(resource) return resource _wait_time = get_exponential_wait(wait_time, counter) _max_wait = max_elapsed_estimate - _wait_time _wait_time = min(_max_wait, _wait_time) if _wait_time <= 0: # when the max_expected_elapsed time is met, we still wait for # the resource to be finished but we restart all counters and # the exponentially growing time is initialized _wait_time = wait_time counter = 0 elapsed = 0 if debug: print("Sleeping %s" % _wait_time) time.sleep(_wait_time) elapsed += _wait_time # retries for the finished status use a query string that gets the # minimal available resource if kwargs.get('query_string') is not None: tiny_kwargs = {'query_string': c.TINY_RESOURCE} else: tiny_kwargs = {} if debug: print("Getting only status for resource %s" % resource_id) resource = get_method(resource, **tiny_kwargs) if raise_on_error: exception_on_error(resource) return resource