
    J                     Z    d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d de	      Z
y	)
z1Common download workflow used by GCS API clients.    )absolute_import)division)unicode_literals)
retry_util)logc                   0    e Zd ZdZd Zd Zd Zd ZddZy)	GcsDownloadz(Base class for performing GCS downloads.c                 <    || _         || _        || _        || _        y)a  Initializes a GcsDownload instance.

    Args:
      download_stream (stream): Stream to send the object data to.
      start_byte (int): Starting point for download (for resumable downloads and
        range requests). Can be set to negative to request a range of bytes
        (python equivalent of [:-3]).
      end_byte (int): Ending byte number, inclusive, for download (for range
        requests). If None, download the rest of the object.

    N)_download_stream_initial_start_byte	_end_byte_start_byte)selfdownload_stream
start_byteend_bytes       2lib/googlecloudsdk/api_lib/storage/gcs_download.py__init__zGcsDownload.__init__   s#     ,D)DDN!D    c                     t               )z,Returns True if the error should be retried.NotImplementedError)r   exc_type	exc_valueexc_tracebacks       r   should_retryzGcsDownload.should_retry-   s    

r   c                     t               )a?  Performs the download.

    The child classes should implement this function.

    Returns:
      Encoding string for object if requested. Otherwise, None.

    Raises:
      CloudApiError: API returned an error.
      NotImplementedError: This function was not implemented by a class using
        this interface.
    r   )r   s    r   launchzGcsDownload.launch1   s     
r   c                     | j                  |||      sy| j                  j                         }|| j                  kD  r|| _        d|_        t        j                  dj                  |||             y)a  Returns True if the error should be retried.

    This method also updates the start_byte to be used for request
    to be retried.

    Args:
      exc_type (type): The type of Exception.
      exc_value (Exception): The error instance.
      exc_traceback (traceback): The traceback for the exception.
      state (core.util.retry.RetryState): The state object
        maintained by the retryer.

    Returns:
      True if the error should be retried.
    Fr   z=Retrying download from byte {} after exception: {}. Trace: {}T)r   r   tellr   retrialr   debugformat)r   r   r   r   stater   s         r   _should_retry_wrapperz!GcsDownload._should_retry_wrapper@   so      Xy-@ &&++-JD$$$#demII !6*hFHr   c                 |    |s| j                         S t        j                  | j                   | j                        S )zPerforms downlaod.

    Args:
      retriable_in_flight (bool): Indicates if a download can be retried
        on network error, resuming the download from the last downloaded byte.

    Returns:
      The result returned by launch method.
    )targetshould_retry_if)r   r   retryerr%   )r   retriable_in_flights     r   runzGcsDownload.run]   s7     [[]{{D,F,FH Hr   N)T)	__name__
__module____qualname____doc__r   r   r   r%   r+    r   r   r	   r	      s    0""  :Hr   r	   N)r/   
__future__r   r   r   googlecloudsdk.api_lib.storager   googlecloudsdk.corer   objectr	   r0   r   r   <module>r5      s)    8 &  ' 5 #RH& RHr   