in firebase_admin/ml.py [0:0]
def handle_operation(self, operation, wait_for_operation=False, max_time_seconds=None):
"""Handles long running operations.
Args:
operation: The operation to handle.
wait_for_operation: Should we allow polling for the operation to complete.
If no polling is requested, a locked model will be returned instead.
max_time_seconds: The maximum seconds to try polling for operation complete.
(None for no limit)
Returns:
dict: A dictionary of the returned model properties.
Raises:
TypeError: if the operation is not a dictionary.
ValueError: If the operation is malformed.
UnknownError: If the server responds with an unexpected response.
err: If the operation exceeds polling attempts or stop_time
"""
if not isinstance(operation, dict):
raise TypeError('Operation must be a dictionary.')
if operation.get('done'):
# Operations which are immediately done don't have an operation name
if operation.get('response'):
return operation.get('response')
if operation.get('error'):
raise _utils.handle_operation_error(operation.get('error'))
raise exceptions.UnknownError(message='Internal Error: Malformed Operation.')
op_name = _validate_operation_name(operation.get('name'))
metadata = operation.get('metadata', {})
metadata_type = metadata.get('@type', '')
if not metadata_type.endswith('ModelOperationMetadata'):
raise TypeError('Unknown type of operation metadata.')
_, model_id = _validate_and_parse_name(metadata.get('name'))
current_attempt = 0
start_time = datetime.datetime.now()
stop_time = (None if max_time_seconds is None else
start_time + datetime.timedelta(seconds=max_time_seconds))
while wait_for_operation and not operation.get('done'):
# We just got this operation. Wait before getting another
# so we don't exceed the GetOperation maximum request rate.
self._exponential_backoff(current_attempt, stop_time)
operation = self.get_operation(op_name)
current_attempt += 1
if operation.get('done'):
if operation.get('response'):
return operation.get('response')
if operation.get('error'):
raise _utils.handle_operation_error(operation.get('error'))
# If the operation is not complete or timed out, return a (locked) model instead
return get_model(model_id).as_dict()