
    (ph                     H   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SSKrSS
KJr  SSKJr  SSKJr  SrSrSr SSSSSSS.r!Sr"Sr#Sr$0 r%S r&\&SSSSS\"\4S j5       r'\&SSSS\"\4SS.S jj5       r(\&SSSSSSSS\"\4
SS .S! jj5       r)\&SSSSSS"S\"\4	SS.S# jj5       r*\SS\"\4S"S$.S% jjr+S\S\"\4S&\\S'.S( jjr,S) r-S* r.S+ r/ " S, S-5      r0S. r1S/ r2S0 r3S1 r4S2 r5 " S3 S45      r6g)5zConcurrent media operations.    N)
exceptions)Client)Blob)_get_host_name)_quote)_DEFAULT_TIMEOUT)DEFAULT_RETRY)XMLMPUContainer)
XMLMPUPart)DataCorruptioni      i  @ zCache-ControlzContent-DispositionzContent-EncodingzContent-Languagezx-goog-custom-timezx-goog-storage-class)cacheControlcontentDispositioncontentEncodingcontentLanguage
customTimestorageClassprocessthreadzChecksum mismatch while downloading:

  {}

The object metadata indicated a crc32c checksum of:

  {}

but the actual crc32c checksum of the downloaded contents was:

  {}
c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )Nc                    > [         R                  " T5      R                  " U 0 UD6nUR                  R	                  S5      nU(       a  UR                  R	                  S5      nUR                  R	                  S5      nU(       d  U(       a  [        S5      e[        R                  " S5        UR                  n UR                  n[        US'   X1S'   T" U 0 UD6$ T" U 0 UD6$ )Nthreadsworker_typemax_workerszuThe `threads` parameter is deprecated and conflicts with its replacement parameters, `worker_type` and `max_workers`.zeThe `threads` parameter is deprecated. Please use `worker_type` and `max_workers` parameters instead.)inspect	signaturebind	argumentsget
ValueErrorwarningswarnargskwargsTHREAD)r#   r$   bindingr   r   r   funcs         X/var/www/html/venv/lib/python3.13/site-packages/google/cloud/storage/transfer_manager.pyconvert_threads_or_raise:_deprecate_threads_param.<locals>.convert_threads_or_raiseN   s    ##D)..??##''	2!++//>K!++//>Kk  L  MMw <<D^^F$*F=!$+=!((((((    )	functoolswraps)r'   r)   s   ` r(   _deprecate_threads_paramr.   M   s&    __T) ), $#r+   Fc                 Z   Uc  0 nU(       a  UR                  5       nSUS'   SUS'   [        U5      u  pU" US9 n
/ nU  H~  u  pU	(       a   [        U[        5      (       d  [	        S5      eUR                  U
R                  " [        U	(       a  [        U5      OU[        U[        5      (       a  SOS	U40 UD65        M     [        R                  R                  X[        R                  R                  S
9  SSS5        / nW H  nUR                  5       nU(       a  U(       d  UR                  U5        M4  U(       a9  U(       a2  [        U[        R                  5      (       a  UR                  U5        Mt  UR                  UR!                  5       5        M     U$ ! , (       d  f       N= f)a(  Upload many files concurrently via a worker pool.

:type file_blob_pairs: List(Tuple(IOBase or str, 'google.cloud.storage.blob.Blob'))
:param file_blob_pairs:
    A list of tuples of a file or filename and a blob. Each file will be
    uploaded to the corresponding blob by using APIs identical to
    `blob.upload_from_file()` or `blob.upload_from_filename()` as
    appropriate.

    File handlers are only supported if worker_type is set to THREAD.
    If worker_type is set to PROCESS, please use filenames only.

:type skip_if_exists: bool
:param skip_if_exists:
    If True, blobs that already have a live version will not be overwritten.
    This is accomplished by setting `if_generation_match = 0` on uploads.
    Uploads so skipped will result in a 412 Precondition Failed response
    code, which will be included in the return value but not raised
    as an exception regardless of the value of raise_exception.

:type upload_kwargs: dict
:param upload_kwargs:
    A dictionary of keyword arguments to pass to the upload method. Refer
    to the documentation for `blob.upload_from_file()` or
    `blob.upload_from_filename()` for more information. The dict is directly
    passed into the upload methods and is not validated by this function.

:type threads: int
:param threads:
    ***DEPRECATED*** Sets `worker_type` to THREAD and `max_workers` to the
    number specified. If `worker_type` or `max_workers` are set explicitly,
    this parameter should be set to None. Please use `worker_type` and
    `max_workers` instead of this parameter.

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type raise_exception: bool
:param raise_exception:
    If True, instead of adding exceptions to the list of return values,
    instead they will be raised. Note that encountering an exception on one
    operation will not prevent other operations from starting. Exceptions
    are only processed and potentially raised after all operations are
    complete in success or failure.

    If skip_if_exists is True, 412 Precondition Failed responses are
    considered part of normal operation and are not raised as an exception.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

    PROCESS workers do not support writing to file handlers. Please refer
    to files by filename only when using PROCESS workers.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:raises: :exc:`concurrent.futures.TimeoutError` if deadline is exceeded.

:rtype: list
:returns: A list of results corresponding to, in order, each item in the
    input list. If an exception was received, it will be the result
    for that operation. Otherwise, the return value from the successful
    upload method is used (which will be None).
Nr   if_generation_matchztm.upload_manycommandr   Passing in a file object is only supported by the THREAD worker type. Please either select THREAD workers, or pass in filenames only._handle_filename_and_upload_prep_and_do_uploadtimeoutreturn_when)copy _get_pool_class_and_requirements
isinstancestrr    appendsubmit"_call_method_on_maybe_pickled_blob_pickle_client
concurrentfutureswaitALL_COMPLETED	exceptionr   PreconditionFailedresult)file_blob_pairsskip_if_existsupload_kwargsr   deadlineraise_exceptionr   r   
pool_classneeds_picklingexecutorrB   path_or_fileblobresultsfutureexps                    r(   upload_manyrU   h   sy   R %**,/0+,/M)!A+!NJ		,"1L js&C&C  \  NN6,:N4(!,44 2.  $
 #2& 	:3E3E3S3S 	  	
+ 
-2 G  NN3^
3
8U8U(V(VNN3 NN6==?+  NO 
-	,s   B=F
F*)rI   c                &   Uc  0 nSUS'   [        U5      u  pU" US9 n
/ nU  H  u  pU	(       a   [        U[        5      (       d  [        S5      eU(       a;  [        U[        5      (       a&  [        R
                  R                  U5      (       a  Mn  UR                  U
R                  " [        U	(       a  [        U5      OU[        U[        5      (       a  SOSU40 UD65        M     [        R                  R                  X[        R                  R                  S9  SSS5        / nW HS  nU(       d*  UR                  5       nU(       a  UR                  U5        M4  UR                  UR!                  5       5        MU     U$ ! , (       d  f       Nk= f)	a  Download many blobs concurrently via a worker pool.

:type blob_file_pairs: List(Tuple('google.cloud.storage.blob.Blob', IOBase or str))
:param blob_file_pairs:
    A list of tuples of blob and a file or filename. Each blob will be downloaded to the corresponding blob by using APIs identical to blob.download_to_file() or blob.download_to_filename() as appropriate.

    Note that blob.download_to_filename() does not delete the destination file if the download fails.

    File handlers are only supported if worker_type is set to THREAD.
    If worker_type is set to PROCESS, please use filenames only.

:type download_kwargs: dict
:param download_kwargs:
    A dictionary of keyword arguments to pass to the download method. Refer
    to the documentation for `blob.download_to_file()` or
    `blob.download_to_filename()` for more information. The dict is directly
    passed into the download methods and is not validated by this function.

:type threads: int
:param threads:
    ***DEPRECATED*** Sets `worker_type` to THREAD and `max_workers` to the
    number specified. If `worker_type` or `max_workers` are set explicitly,
    this parameter should be set to None. Please use `worker_type` and
    `max_workers` instead of this parameter.

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type raise_exception: bool
:param raise_exception:
    If True, instead of adding exceptions to the list of return values,
    instead they will be raised. Note that encountering an exception on one
    operation will not prevent other operations from starting. Exceptions
    are only processed and potentially raised after all operations are
    complete in success or failure.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

    PROCESS workers do not support writing to file handlers. Please refer
    to files by filename only when using PROCESS workers.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:type skip_if_exists: bool
:param skip_if_exists:
    Before downloading each blob, check if the file for the filename exists;
    if it does, skip that blob.

:raises: :exc:`concurrent.futures.TimeoutError` if deadline is exceeded.

:rtype: list
:returns: A list of results corresponding to, in order, each item in the
    input list. If an exception was received, it will be the result
    for that operation. Otherwise, the return value from the successful
    download method is used (which will be None).
Nztm.download_manyr1   r2   r3   _handle_filename_and_download_prep_and_do_downloadr6   )r:   r;   r<   r    ospathisfiler=   r>   r?   r@   rA   rB   rC   rD   rE   rG   )blob_file_pairsdownload_kwargsr   rK   rL   r   r   rI   rM   rN   rO   rB   rQ   rP   rR   rS   rT   s                    r(   download_manyr^     s_   H !3OI!A+!NJ		,"1D js&C&C  \  *\3"?"?77>>,//NN6,:N4(!,44 40  &
 #2. 	:3E3E3S3S 	  	
3 
-: G""$Cs#v}}'  NO 
-	,s   C?F
F )additional_blob_attributesc          
      *   Uc  0 nUc  0 n/ nU Hs  n[         R                  R                  X.5      nX>-   nU R                  " U40 UD6nUR	                  5        H  u  nn[        UUU5        M     UR                  UU45        Mu     [        UUUUU	U
US9$ )a  Upload many files concurrently by their filenames.

The destination blobs are automatically created, with blob names based on
the source filenames and the blob_name_prefix.

For example, if the `filenames` include "images/icon.jpg",
`source_directory` is "/home/myuser/", and `blob_name_prefix` is "myfiles/",
then the file at "/home/myuser/images/icon.jpg" will be uploaded to a blob
named "myfiles/images/icon.jpg".

:type bucket: :class:`google.cloud.storage.bucket.Bucket`
:param bucket:
    The bucket which will contain the uploaded blobs.

:type filenames: list(str)
:param filenames:
    A list of filenames to be uploaded. This may include part of the path.
    The file will be accessed at the full path of `source_directory` +
    `filename`.

:type source_directory: str
:param source_directory:
    A string that will be prepended (with `os.path.join()`) to each filename
    in the input list, in order to find the source file for each blob.
    Unlike the filename itself, the source_directory does not affect the
    name of the uploaded blob.

    For instance, if the source_directory is "/tmp/img/" and a filename is
    "0001.jpg", with an empty blob_name_prefix, then the file uploaded will
    be "/tmp/img/0001.jpg" and the destination blob will be "0001.jpg".

    This parameter can be an empty string.

    Note that this parameter allows directory traversal (e.g. "/", "../")
    and is not intended for unsanitized end user input.

:type blob_name_prefix: str
:param blob_name_prefix:
    A string that will be prepended to each filename in the input list, in
    order to determine the name of the destination blob. Unlike the filename
    itself, the prefix string does not affect the location the library will
    look for the source data on the local filesystem.

    For instance, if the source_directory is "/tmp/img/", the
    blob_name_prefix is "myuser/mystuff-" and a filename is "0001.jpg" then
    the file uploaded will be "/tmp/img/0001.jpg" and the destination blob
    will be "myuser/mystuff-0001.jpg".

    The blob_name_prefix can be blank (an empty string).

:type skip_if_exists: bool
:param skip_if_exists:
    If True, blobs that already have a live version will not be overwritten.
    This is accomplished by setting `if_generation_match = 0` on uploads.
    Uploads so skipped will result in a 412 Precondition Failed response
    code, which will be included in the return value, but not raised
    as an exception regardless of the value of raise_exception.

:type blob_constructor_kwargs: dict
:param blob_constructor_kwargs:
    A dictionary of keyword arguments to pass to the blob constructor. Refer
    to the documentation for `blob.Blob()` for more information. The dict is
    directly passed into the constructor and is not validated by this
    function. `name` and `bucket` keyword arguments are reserved by this
    function and will result in an error if passed in here.

:type upload_kwargs: dict
:param upload_kwargs:
    A dictionary of keyword arguments to pass to the upload method. Refer
    to the documentation for `blob.upload_from_file()` or
    `blob.upload_from_filename()` for more information. The dict is directly
    passed into the upload methods and is not validated by this function.

:type threads: int
:param threads:
    ***DEPRECATED*** Sets `worker_type` to THREAD and `max_workers` to the
    number specified. If `worker_type` or `max_workers` are set explicitly,
    this parameter should be set to None. Please use `worker_type` and
    `max_workers` instead of this parameter.

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type raise_exception: bool
:param raise_exception:
    If True, instead of adding exceptions to the list of return values,
    instead they will be raised. Note that encountering an exception on one
    operation will not prevent other operations from starting. Exceptions
    are only processed and potentially raised after all operations are
    complete in success or failure.

    If skip_if_exists is True, 412 Precondition Failed responses are
    considered part of normal operation and are not raised as an exception.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:type additional_blob_attributes: dict
:param additional_blob_attributes:
    A dictionary of blob attribute names and values. This allows the
    configuration of blobs beyond what is possible with
    blob_constructor_kwargs. For instance, {"cache_control": "no-cache"}
    would set the cache_control attribute of each blob to "no-cache".

    As with blob_constructor_kwargs, this affects the creation of every
    blob identically. To fine-tune each blob individually, use `upload_many`
    and create the blobs as desired before passing them in.

:raises: :exc:`concurrent.futures.TimeoutError` if deadline is exceeded.

:rtype: list
:returns: A list of results corresponding to, in order, each item in the
    input list. If an exception was received, it will be the result
    for that operation. Otherwise, the return value from the successful
    upload method is used (which will be None).
)rI   rJ   rK   rL   r   r   )rY   rZ   joinrQ   itemssetattrr=   rU   )bucket	filenamessource_directoryblob_name_prefixrI   blob_constructor_kwargsrJ   r   rK   rL   r   r   r`   rH   filenamerZ   	blob_namerQ   propvalues                       r(   upload_many_from_filenamesrn     s    J &"$!)%'"Oww||,7$/	{{9@(?@5;;=KD%D$& >d|,  %#' r+   Tc          
      <   / nU H  nX=-   n[         R                  R                  X-5      nU(       a7  [         R                  R                  U5      u  nn[         R                  " USS9  UR                  U R                  U5      U45        M     [        UUUUU	U
US9$ )a|  Download many files concurrently by their blob names.

The destination files are automatically created, with paths based on the
source blob_names and the destination_directory.

The destination files are not automatically deleted if their downloads fail,
so please check the return value of this function for any exceptions, or
enable `raise_exception=True`, and process the files accordingly.

For example, if the `blob_names` include "icon.jpg", `destination_directory`
is "/home/myuser/", and `blob_name_prefix` is "images/", then the blob named
"images/icon.jpg" will be downloaded to a file named
"/home/myuser/icon.jpg".

:type bucket: :class:`google.cloud.storage.bucket.Bucket`
:param bucket:
    The bucket which contains the blobs to be downloaded

:type blob_names: list(str)
:param blob_names:
    A list of blobs to be downloaded. The blob name in this string will be
    used to determine the destination file path as well.

    The full name to the blob must be blob_name_prefix + blob_name. The
    blob_name is separate from the blob_name_prefix because the blob_name
    will also determine the name of the destination blob. Any shared part of
    the blob names that need not be part of the destination path should be
    included in the blob_name_prefix.

:type destination_directory: str
:param destination_directory:
    A string that will be prepended (with os.path.join()) to each blob_name
    in the input list, in order to determine the destination path for that
    blob.

    For instance, if the destination_directory string is "/tmp/img" and a
    blob_name is "0001.jpg", with an empty blob_name_prefix, then the source
    blob "0001.jpg" will be downloaded to destination "/tmp/img/0001.jpg" .

    This parameter can be an empty string.

    Note that this parameter allows directory traversal (e.g. "/", "../")
    and is not intended for unsanitized end user input.

:type blob_name_prefix: str
:param blob_name_prefix:
    A string that will be prepended to each blob_name in the input list, in
    order to determine the name of the source blob. Unlike the blob_name
    itself, the prefix string does not affect the destination path on the
    local filesystem. For instance, if the destination_directory is
    "/tmp/img/", the blob_name_prefix is "myuser/mystuff-" and a blob_name
    is "0001.jpg" then the source blob "myuser/mystuff-0001.jpg" will be
    downloaded to "/tmp/img/0001.jpg". The blob_name_prefix can be blank
    (an empty string).

:type download_kwargs: dict
:param download_kwargs:
    A dictionary of keyword arguments to pass to the download method. Refer
    to the documentation for `blob.download_to_file()` or
    `blob.download_to_filename()` for more information. The dict is directly
    passed into the download methods and is not validated by this function.

:type threads: int
:param threads:
    ***DEPRECATED*** Sets `worker_type` to THREAD and `max_workers` to the
    number specified. If `worker_type` or `max_workers` are set explicitly,
    this parameter should be set to None. Please use `worker_type` and
    `max_workers` instead of this parameter.

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type create_directories: bool
:param create_directories:
    If True, recursively create any directories that do not exist. For
    instance, if downloading object "images/img001.png", create the
    directory "images" before downloading.

:type raise_exception: bool
:param raise_exception:
    If True, instead of adding exceptions to the list of return values,
    instead they will be raised. Note that encountering an exception on one
    operation will not prevent other operations from starting. Exceptions
    are only processed and potentially raised after all operations are
    complete in success or failure. If skip_if_exists is True, 412
    Precondition Failed responses are considered part of normal operation
    and are not raised as an exception.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:type skip_if_exists: bool
:param skip_if_exists:
    Before downloading each blob, check if the file for the filename exists;
    if it does, skip that blob. This only works for filenames.

:raises: :exc:`concurrent.futures.TimeoutError` if deadline is exceeded.

:rtype: list
:returns: A list of results corresponding to, in order, each item in the
    input list. If an exception was received, it will be the result
    for that operation. Otherwise, the return value from the successful
    download method is used (which will be None).
T)exist_ok)r]   rK   rL   r   r   rI   )rY   rZ   rb   splitmakedirsr=   rQ   r^   )re   
blob_namesdestination_directoryrh   r]   r   rK   create_directoriesrL   r   r   rI   r\   rk   full_blob_namerZ   	directory_s                     r(   download_many_to_pathry   Z  s    p O	)5ww||1=77==.LIqKK	D1N ;TBC   ''% r+   )crc32c_checksumc                   U R                   nUc  0 nSU;   d  SU;   a  [        S5      eSU;   a  [        S5      eUR                  5       nSUS'   SUS'   U R                  (       a  U R                  (       d  U R                  5         [        U5      u  pU
(       a  [        U 5      OU n/ n[        US	5       n SSS5        U	" US
9 nSnU R                  nUU:  aC  Un[        X-   U5      nUR                  UR                  [        UUUUS-
  UUS95        UU:  a  MC  [        R                  R                  X[        R                  R                   S9  SSS5        / nU H"  nUR                  UR#                  5       5        M$     U(       a  U(       a  [%        U5      n[&        R(                  " U5      R+                  S5      nU R,                  nUU:w  ap  U R/                  UUR1                  S5      UR1                  S5      UR1                  S5      UR1                  S5      S9n[3        S[4        R7                  UUU5      5      eg! , (       d  f       GN= f! , (       d  f       GN= f)a"  Download a single file in chunks, concurrently.

In some environments, using this feature with mutiple processes will result
in faster downloads of large files.

Using this feature with multiple threads is unlikely to improve download
performance under normal circumstances due to Python interpreter threading
behavior. The default is therefore to use processes instead of threads.

:type blob: :class:`google.cloud.storage.blob.Blob`
:param blob:
    The blob to be downloaded.

:type filename: str
:param filename:
    The destination filename or path.

:type chunk_size: int
:param chunk_size:
    The size in bytes of each chunk to send. The optimal chunk size for
    maximum throughput may vary depending on the exact network environment
    and size of the blob.

:type download_kwargs: dict
:param download_kwargs:
    A dictionary of keyword arguments to pass to the download method. Refer
    to the documentation for `blob.download_to_file()` or
    `blob.download_to_filename()` for more information. The dict is directly
    passed into the download methods and is not validated by this function.

    Keyword arguments "start" and "end" which are not supported and will
    cause a ValueError if present. The key "checksum" is also not supported
    in `download_kwargs`, but see the argument `crc32c_checksum` (which does
    not go in `download_kwargs`) below.

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:type crc32c_checksum: bool
:param crc32c_checksum:
    Whether to compute a checksum for the resulting object, using the crc32c
    algorithm. As the checksums for each chunk must be combined using a
    feature of crc32c that is not available for md5, md5 is not supported.

:raises:
    :exc:`concurrent.futures.TimeoutError`
        if deadline is exceeded.
    :exc:`google.cloud.storage._media.common.DataCorruption`
        if the download's checksum doesn't agree with server-computed
        checksum. The `google.cloud.storage._media` exception is used here for
        consistency with other download methods despite the exception
        originating elsewhere.
NstartendzWDownload arguments 'start' and 'end' are not supported by download_chunks_concurrently.checksumz'checksum' is in download_kwargs, but is not supported because sliced downloads have a different checksum mechanism from regular downloads. Use the 'crc32c_checksum' argument on download_chunks_concurrently instead.ztm.download_shardedr1   wbr2   r      )r|   r}   r]   rz   r6   zutf-8r0   if_generation_not_matchif_metageneration_matchif_metageneration_not_match)r0   r   r   r   )clientr    r9   size
generationreloadr:   r@   openminr=   r>   "_download_and_write_chunk_in_placerA   rB   rC   rD   rG   '_digest_ordered_checksum_and_size_pairsbase64	b64encodedecodecrc32c_get_download_urlr   r   !DOWNLOAD_CRC32C_MISMATCH_TEMPLATEformat)rQ   rj   
chunk_sizer]   rK   r   r   rz   r   rM   rN   maybe_pickled_blobrB   rx   rO   cursorr}   r|   rR   rS   
crc_digestactual_checksumexpected_checksumdownload_urls                           r(   download_chunks_concurrentlyr     sg   F [[F/!Uo%=e
 	
 _$ f
 	
 &**,O"&OJ!6OI 99DOO!A+!NJ1?-TG 
h	 
 
	,iislE,c2FNN6&
$3$3   
 sl 	:3E3E3S3S 	  	
% 
-. Gv}}'  7<WE
 **:6==gF KK//  11$3$7$78M$N(7(;(;<U(V(7(;(;<U(V,;,?,?1- 2 L !188 "3_  k 
	 
-	,s   5IAI6I
I
I'auto)r~   r7   retryc                   UR                   n
UR                  nUR                  U5      n[        UR                  5      nSR                  XR                  [        UR                  5      S9nUR                  XU SS9u  nnn0 UE[        U5      EnUR                  b  UR                  US'   UR                  b  SUR                  ;  a  UR                  US'   [        XUU	S	9nUR                  XS
9  UR                  n[        R                   R#                  U 5      nUU* -  * n[%        U5      u  nnU(       a  ['        U5      OUn/ nU" US9 n[)        SUS-   5       HF  nUS-
  U-  n[+        UU-  U5      nUR-                  UR/                  [0        UUUU UUUUUU	S95        MH     [2        R4                  R7                  UU[2        R4                  R8                  S9  SSS5         U H(  nUR;                  5       u  nnUR=                  UU5        M*     UR?                  UR                  U5      5        g! , (       d  f       N^= f! [@         a"    URC                  UR                  U5      5        e f = f)a  Upload a single file in chunks, concurrently.

This function uses the XML MPU API to initialize an upload and upload a
file in chunks, concurrently with a worker pool.

The XML MPU API is significantly different from other uploads; please review
the documentation at `https://cloud.google.com/storage/docs/multipart-uploads`
before using this feature.

The library will attempt to cancel uploads that fail due to an exception.
If the upload fails in a way that precludes cancellation, such as a
hardware failure, process termination, or power outage, then the incomplete
upload may persist indefinitely. To mitigate this, set the
`AbortIncompleteMultipartUpload` with a nonzero `Age` in bucket lifecycle
rules, or refer to the XML API documentation linked above to learn more
about how to list and delete individual downloads.

Using this feature with multiple threads is unlikely to improve upload
performance under normal circumstances due to Python interpreter threading
behavior. The default is therefore to use processes instead of threads.

ACL information cannot be sent with this function and should be set
separately with :class:`ObjectACL` methods.

:type filename: str
:param filename:
    The path to the file to upload. File-like objects are not supported.

:type blob: :class:`google.cloud.storage.blob.Blob`
:param blob:
    The blob to which to upload.

:type content_type: str
:param content_type: (Optional) Type of content being uploaded.

:type chunk_size: int
:param chunk_size:
    The size in bytes of each chunk to send. The optimal chunk size for
    maximum throughput may vary depending on the exact network environment
    and size of the blob. The remote API has restrictions on the minimum
    and maximum size allowable, see: `https://cloud.google.com/storage/quotas#requests`

:type deadline: int
:param deadline:
    The number of seconds to wait for all threads to resolve. If the
    deadline is reached, all threads will be terminated regardless of their
    progress and `concurrent.futures.TimeoutError` will be raised. This can
    be left as the default of `None` (no deadline) for most use cases.

:type worker_type: str
:param worker_type:
    The worker type to use; one of `google.cloud.storage.transfer_manager.PROCESS`
    or `google.cloud.storage.transfer_manager.THREAD`.

    Although the exact performance impact depends on the use case, in most
    situations the PROCESS worker type will use more system resources (both
    memory and CPU) and result in faster operations than THREAD workers.

    Because the subprocesses of the PROCESS worker type can't access memory
    from the main process, Client objects have to be serialized and then
    recreated in each subprocess. The serialization of the Client object
    for use in subprocesses is an approximation and may not capture every
    detail of the Client object, especially if the Client was modified after
    its initial creation or if `Client._http` was modified in any way.

    THREAD worker types are observed to be relatively efficient for
    operations with many small files, but not for operations with large
    files. PROCESS workers are recommended for large file operations.

:type max_workers: int
:param max_workers:
    The maximum number of workers to create to handle the workload.

    With PROCESS workers, a larger number of workers will consume more
    system resources (memory and CPU) at once.

    How many workers is optimal depends heavily on the specific use case,
    and the default is a conservative number that should work okay in most
    cases without consuming excessive resources.

:type checksum: str
:param checksum:
    (Optional) The checksum scheme to use: either "md5", "crc32c", "auto"
    or None. The default is "auto", which will try to detect if the C
    extension for crc32c is installed and fall back to md5 otherwise.
    Each individual part is checksummed. At present, the selected
    checksum rule is only applied to parts and a separate checksum of the
    entire resulting blob is not computed. Please compute and compare the
    checksum of the file to the resulting blob separately if needed, using
    the "crc32c" algorithm as per the XML MPU documentation.

:type timeout: float or tuple
:param timeout:
    (Optional) The amount of time, in seconds, to wait
    for the server response.  See: :ref:`configuring_timeouts`

:type retry: google.api_core.retry.Retry
:param retry: (Optional) How to retry the RPC. A None value will disable
    retries. A `google.api_core.retry.Retry` value will enable retries,
    and the object will configure backoff and timeout options. Custom
    predicates (customizable error codes) are not supported for media
    operations such as this one.

    This function does not accept `ConditionalRetryPolicy` values because
    preconditions are not supported by the underlying API call.

    See the retry.py source code and docstrings in this package
    (`google.cloud.storage.retry`) for information on retry types and how
    to configure them.

:raises: :exc:`concurrent.futures.TimeoutError` if deadline is exceeded.
z{hostname}/{bucket}/{blob})hostnamere   rQ   ztm.upload_sharded)rj   r1   Nzx-goog-user-projectcryptoKeyVersionszx-goog-encryption-kms-key-name)headersr   )	transportcontent_typer2   r   r|   r}   part_numberr~   r   r   r6   )"re   r   _get_transportr   _connectionr   namer   _get_upload_arguments_headers_from_metadatauser_projectkms_key_namer
   initiate	upload_idrY   rZ   getsizer:   r@   ranger   r=   r>   _upload_partrA   rB   rC   rD   rG   register_partfinalize	Exceptioncancel) rj   rQ   r   r   rK   r   r   r~   r7   r   re   r   r   r   urlbase_headersobject_metadatar   	containerr   r   num_of_partsrM   rN   maybe_pickled_clientrB   rO   r   r|   r}   rS   etags                                    r(   upload_chunks_concurrentlyr     s   | [[F[[F##F+If001H
&
-
-++F4994E . C 372L2Lx9L 3M 3/L/< JI!7!HIG$)-):):%& $)<DDUDU)U484E4E01weLIF##I77??8$Dj[()L!A+!NJ5C>&1G		, L1$45K 1_
2EkJ.5CNN ( +%#   	 6( 	X:3E3E3S3S 	  	
+ 
-2	F &K##K6  	4..v67? 
-	,@  ,,V45s   BH7(AI 7
I,I4c
                     [        U [        5      (       a  U n
O[        R                  " U 5      n
[	        UUUUUUUUU	S9	nUR                  U
R                  5        XkR                  4$ )zHelper function that runs inside a thread or subprocess to upload a part.

`maybe_pickled_client` is either a Client (for threads) or a specially
pickled Client (for processes) because the default pickling mangles Client
objects.r   )r;   r   pickleloadsr   upload_httpr   )r   r   r   rj   r|   r}   r   r~   r   r   r   parts               r(   r   r     sj    $ &//%23
D 	KK##r+   c                     0 nU R                  5        H  u  p#U[        ;   d  M  X1[        U   '   M     SU ;   a#  U S   R                  5        H  u  p#X1SU-   '   M     U$ )zFHelper function to translate object metadata into a header dictionary.metadatazx-goog-meta-)rc   METADATA_HEADER_TRANSLATION)r   r   keyrm   s       r(   r   r     si     Gnn&
--8=/45 ' X":.446JC,1NS() 7Nr+   c                     [        U [        5      (       a  U nO[        R                  " U 5      n[	        XU5       nUR
                  " U4X#S.UD6  UR                  X2-
  S-   4sSSS5        $ ! , (       d  f       g= f)a(  Helper function that runs inside a thread or subprocess.

`maybe_pickled_blob` is either a Blob (for threads) or a specially pickled
Blob (for processes) because the default pickling mangles Client objects
which are attached to Blobs.

Returns a crc if configured (or None) and the size written.
)r|   r}   r   N)r;   r   r   r   _ChecksummingSparseFileWrapperrX   crc)r   rj   r|   r}   r]   rz   rQ   fs           r(   r   r     sj     $d++!||./	'	IQ""1NENoNq() 
J	I	Is   (A--
A;c                   @    \ rS rSrSrS rS r\S 5       rS r	S r
Srg	)
r   i  zA file wrapper that writes to a sparse file and optionally checksums.

This wrapper only implements write() and does not inherit from `io` module
base classes.
c                 v    [        US5      U l        U R                  R                  U5        S U l        X0l        g )Nzrb+)r   r   seek_crc_crc32c_enabled)selfrj   start_positioncrc32c_enableds       r(   __init__'_ChecksummingSparseFileWrapper.__init__  s-    h&N#	-r+   c                     U R                   (       aO  U R                  c  [        R                  " U5      U l        O&[        R                  " U R                  U5      U l        U R
                  R                  U5        g N)r   r   google_crc32crm   extendr   write)r   chunks     r(   r   $_ChecksummingSparseFileWrapper.write  sO    yy )//6	)00EB	Ur+   c                     U R                   $ r   )r   r   s    r(   r   "_ChecksummingSparseFileWrapper.crc  s    yyr+   c                     U $ r    r   s    r(   	__enter__(_ChecksummingSparseFileWrapper.__enter__  s    r+   c                 8    U R                   R                  5         g r   )r   close)r   exc_type	exc_valuetbs       r(   __exit__'_ChecksummingSparseFileWrapper.__exit__  s    r+   )r   r   r   N)__name__
__module____qualname____firstlineno____doc__r   r   propertyr   r   r   __static_attributes__r   r+   r(   r   r     s/    .  r+   r   c                     [        U [        5      (       a  U nO[        R                  " U 5      n[	        XA5      " U0 UD6$ )zHelper function that runs inside a thread or subprocess.

`maybe_pickled_blob` is either a Blob (for threads) or a specially pickled
Blob (for processes) because the default pickling mangles Client objects
which are attached to Blobs.)r;   r   r   r   getattr)r   method_namer#   r$   rQ   s        r(   r?   r?     s;     $d++!||./4%t6v66r+   c                     [        U 5      nU R                  nU R                  nSnU R                  nU R                  nU R
                  n[        UUUUUUU44$ )zReplicate a Client by constructing a new one with the same params.

LazyClient performs transparent caching for when the same client is needed
on the same process multiple times.N)idproject_credentials_initial_client_info_initial_client_options_extra_headers_LazyClient)clclient_object_idr   credentialsr   client_infoclient_optionsextra_headerss           r(   _reduce_clientr    sm     "vjjG//KE))K//N%%M  r+   c                    [         R                  " 5       n[        R                  " U5      n[        R
                  R                  5       Ul        [        UR
                  [        '   UR                  U 5        UR                  5       $ )z=Pickle a Client or an object that owns a Client (like a Blob))ioBytesIOr   Picklercopyregdispatch_tabler9   r  r   dumpgetvalue)objr   ps      r(   r@   r@     s[     	

AqA--224A-AVFF3K::<r+   c                     U [         :X  a  [        R                  R                  S4$ U [        :X  a  [        R                  R
                  S4$ [        S5      e)zDReturns the pool class, and whether the pool requires pickled Blobs.TFzuThe worker_type must be google.cloud.storage.transfer_manager.PROCESS or google.cloud.storage.transfer_manager.THREAD)PROCESSrA   rB   ProcessPoolExecutorr%   ThreadPoolExecutorr    )r   s    r(   r:   r:   -  sU     g""66==		""55u== D
 	
r+   c                    S n[        [        5      nU  H[  u  p4U(       d  UnM  US-  nSnXT:  a6  [        XE-
  [        5      n[        R                  " XS U 5      nXV-  nXT:  a  M6  US-  nX-  nM]     [
        R                  " SU5      nU$ )Nl    r   z>L)bytesMAX_CRC32C_ZERO_ARRAY_SIZEr   r   r   structpack)checksum_and_size_pairsbase_crczeroespart_crcr   paddeddesired_zeroes_sizer   s           r(   r   r   <  s    H-.F1H
"H
 F-&)4=;U&V#(//AUBU:VW- -
 
"H H! 2" hJ r+   c                       \ rS rSrSrS rSrg)r   iV  zBAn object that will transform into either a cached or a new Clientc                 j    [         R                  U5      nU(       a  U$ [        U0 UD6nU[         U'   U$ r   )_cached_clientsr   r   )clsr   r#   r$   cached_clients        r(   __new___LazyClient.__new__Y  s:    '++B/  "D3F3M"/OB  r+   r   N)r   r   r   r   r   r!  r   r   r+   r(   r   r   V  s
    L!r+   r   )7r   concurrent.futuresrA   r  r   rY   r!   r   r  r  r   r,   google.api_corer   google.cloud.storager   r   google.cloud.storage.blobr   r   google.cloud.storage.constantsr   google.cloud.storage.retryr	   r   +google.cloud.storage._media.requests.uploadr
   r   google.cloud.storage.exceptionsr   TM_DEFAULT_CHUNK_SIZEDEFAULT_MAX_WORKERSr  r   r  r%   r   r  r.   rU   r^   rn   ry   r   r   r   r   r   r   r?   r  r@   r:   r   r   r   r+   r(   <module>r-     s   #  	  	       & ' % 4 , ; 4  G B :(  , #/))&*  	% ! $6  #Z Zz  #Q Q Qh   #{  ${ {|  #i i i^ %#t tt $#G 
GT"$J*, B7 2"
4
! 
!r+   