o
    oĎi\7                     @   sB  d dl m Z mZ d dlZd dlZd dlmZmZ d dlmZm	Z	m
Z
mZmZmZmZmZ d dlZddlmZmZ ddlmZ ddlmZ d	d
lmZ z"erYd dlmZ d dlmZ d dlmZ  d dl!m"Z" d dl#mZ$ W n e%yz   ded _&Y nw zd dl#m'Z' W n e(y   dZ'Y nw edG dd deZ)e)j*e)_dS )    )datetime	timedeltaN)PathPurePosixPath)AnyCallableDictIterableOptionalTYPE_CHECKINGTupleUnion   )Clientregister_client_class)implementation_registry)FileCacheMode   )GSPath)Credentials)Retry)default)DefaultCredentialsError)r   Fgs)transfer_managerc                       s  e Zd ZdZddddddejdddf
deeee	j
f  ded dee ded d	eeeef  d
eeee	j
f  dee deeeef  dee ded f fddZdedeeeef  fddZdedeee	j
f defddZdedee fddZdedefddZd1dedeeeef  fddZd2d!ed"ed#edefd$d%Zd2ded&eddfd'd(Zdeee	j
f dedefd)d*Zdedefd+d,Zd3ded.edefd/d0Z   Z!S )4GSClienta  Client class for Google Cloud Storage which handles authentication with GCP for
    [`GSPath`](../gspath/) instances. See documentation for the
    [`__init__` method][cloudpathlib.gs.gsclient.GSClient.__init__] for detailed authentication
    options.
    Napplication_credentialscredentialsr   projectstorage_clientStorageClientfile_cache_modelocal_cache_dircontent_type_method#download_chunks_concurrently_kwargstimeoutretryr   c                    s   |dur|| _ n8|durt||d| _ n,|durt|| _ n!zt \}}|p(|}t||d| _ W n ty?   t | _ Y nw || _i | _|	durS|	| _| j| jd< |
dur`|
| _	| j	| jd< t
 j|||d dS )a8  Class constructor. Sets up a [`Storage
        Client`](https://googleapis.dev/python/storage/latest/client.html).
        Supports, in this order, the following authentication methods of `Storage Client`.

        - Instantiated and already authenticated `Storage Client`.
        - OAuth2 Credentials object and a project name.
        - File path to a JSON credentials file for a Google service account.
        - Google Cloud SDK default credentials. See [How Application Default Credentials works](https://cloud.google.com/docs/authentication/application-default-credentials)

        If no authentication methods are used,
        then the client will be instantiated as anonymous, which will only have
        access to public buckets.

        Args:
            application_credentials (Optional[Union[str, os.PathLike]]): Path to Google service
                account credentials file.
            credentials (Optional[Credentials]): The OAuth2 Credentials to use for this client.
                See documentation for [`StorageClient`](
                https://googleapis.dev/python/storage/latest/client.html).
            project (Optional[str]): The project which the client acts on behalf of. See
                documentation for [`StorageClient`](
                https://googleapis.dev/python/storage/latest/client.html).
            storage_client (Optional[StorageClient]): Instantiated [`StorageClient`](
                https://googleapis.dev/python/storage/latest/client.html).
            file_cache_mode (Optional[Union[str, FileCacheMode]]): How often to clear the file cache; see
                [the caching docs](https://cloudpathlib.drivendata.org/stable/caching/) for more information
                about the options in cloudpathlib.eums.FileCacheMode.
            local_cache_dir (Optional[Union[str, os.PathLike]]): Path to directory to use as cache
                for downloaded files. If None, will use a temporary directory. Default can be set with
                the `CLOUDPATHLIB_LOCAL_CACHE_DIR` environment variable.
            content_type_method (Optional[Callable]): Function to call to guess media type (mimetype) when
                writing a file to the cloud. Defaults to `mimetypes.guess_type`. Must return a tuple (content type, content encoding).
            download_chunks_concurrently_kwargs (Optional[Dict[str, Any]]): Keyword arguments to pass to
                [`download_chunks_concurrently`](https://cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.transfer_manager#google_cloud_storage_transfer_manager_download_chunks_concurrently)
                for sliced parallel downloads; Only available in `google-cloud-storage` version 2.7.0 or later, otherwise ignored and a warning is emitted.
            timeout (Optional[float]): Cloud Storage [timeout value](https://cloud.google.com/python/docs/reference/storage/1.39.0/retry_timeout)
            retry (Optional[google.api_core.retry.Retry]): Cloud Storage [retry configuration](https://cloud.google.com/python/docs/reference/storage/1.39.0/retry_timeout#configuring-retries)
        N)r   r   r%   r&   )r"   r#   r!   )clientr    from_service_account_jsongoogle_default_authr   create_anonymous_clientr$   blob_kwargsr%   r&   super__init__)selfr   r   r   r   r!   r"   r#   r$   r%   r&   default_project	__class__ T/home/jeff/fluffinator/venv/lib/python3.10/site-packages/cloudpathlib/gs/gsclient.pyr-   (   s4   5

zGSClient.__init__
cloud_pathreturnc                 C   s@   | j |j}||j}|d u rd S |j|j|j|j|jdS )N)etagsizeupdatedcontent_typemd5_hash)	r'   bucketget_blobblobr6   r7   r8   r9   r:   r.   r4   r;   r=   r2   r2   r3   _get_metadata   s   zGSClient._get_metadata
local_pathc                 C   s   | j |j}||j}t|}td ur'| jd ur'tj||fi | j |S td u r5| jd ur5t	d |j
|fi | j |S )NzwIgnoring `download_chunks_concurrently_kwargs` for version of google-cloud-storage that does not support them (<2.7.0).)r'   r;   r<   r=   r   r   r$   download_chunks_concurrentlywarningswarndownload_to_filenamer+   )r.   r4   r@   r;   r=   r2   r2   r3   _download_file   s    zGSClient._download_filec                 C   sn   |j sdS | j|j}||j }|d urdS |j }|r&|ds&|d7 }|jd|d}tt|r5dS d S )Ndirfile/r   )max_resultsprefix)r=   r'   r;   r<   endswith
list_blobsboollist)r.   r4   r;   r=   rJ   fr2   r2   r3   _is_file_or_dir   s   zGSClient._is_file_or_dirc                 C   s&   |j s| j|j S | |dv S )N)rG   rF   )r=   r'   r;   existsrP   )r.   r4   r2   r2   r3   _exists   s   zGSClient._existsFc              	   #   sv    j s|r
td fddj D E d H  d S j  j } j}|r1|ds1|d7 }|rt }|j|dD ]E}t|j	t
|d  jD ]$}||vrnt|dkrn j  j  d| | dfV  || qJ j  j  d|j	 dfV  q<d S |jd|d	}|D ]}	 j  j  d|	j	 dfV  q|jD ]}
 j  j  d|
 dfV  qd S )
NztCannot recursively list all buckets and contents; you can get all the buckets then recursively list each separately.c                 3   s,    | ]}  j t| d fV  qdS )TN)	CloudPathcloud_prefixstr).0br4   r.   r2   r3   	<genexpr>   s
    
z%GSClient._list_dir.<locals>.<genexpr>rH   )rJ   .TF)	delimiterrJ   )r;   NotImplementedErrorr'   list_bucketsr=   rK   setrL   r   namelenparentsrU   rS   rT   addprefixes)r.   r4   	recursiver;   rJ   yielded_dirsoparentiteratorrG   	directoryr2   rX   r3   	_list_dir   sP   

zGSClient._list_dirTsrcdst
remove_srcc           	      C   s   ||kr+| j |j}||j}|jd u rdt i|_nt |jd< |  |S | j |j}| j |j}||j}|j|||jfi | j	 |rR|
  |S )Nr8   )r'   r;   r<   r=   metadatar   utcnowpatch	copy_blobr+   delete)	r.   rk   rl   rm   r;   r=   
src_bucket
dst_bucketsrc_blobr2   r2   r3   
_move_file   s   
zGSClient._move_file
missing_okc                 C   s   |  |}|dkr*dd | j|ddD }| j|j}|D ]	}||  qd S |dkr?| j|j}||j  d S |sHtd| d S )NrF   c                 S   s   g | ]	\}}|s|j qS r2   )r=   )rV   rW   is_dirr2   r2   r3   
<listcomp>  s
    z$GSClient._remove.<locals>.<listcomp>T)rd   rG   zFile does not exist: )rP   rj   r'   r;   r<   rr   r=   FileNotFoundError)r.   r4   rw   file_or_dirblobsr;   r=   r2   r2   r3   _remove  s   
zGSClient._removec                 C   sb   | j |j}||j}i }| jd ur!| t|\}}||d< |jt|fi || j |S )Nr9   )r'   r;   r=   r#   rU   upload_from_filenamer+   )r.   r@   r4   r;   r=   
extra_argsr9   _r2   r2   r3   _upload_file   s   
zGSClient._upload_filec                 C   s    | j |j}||j}|jS )N)r'   
get_bucketr;   r=   
public_urlr>   r2   r2   r3   _get_public_url,  s   zGSClient._get_public_url  expire_secondsc                 C   s4   | j |j}||j}|jdt|ddd}|S )Nv4)secondsGET)version
expirationmethod)r'   r   r;   r=   generate_signed_urlr   )r.   r4   r   r;   r=   urlr2   r2   r3   _generate_presigned_url1  s   z GSClient._generate_presigned_url)F)T)r   )"__name__
__module____qualname____doc__	mimetypes
guess_typer
   r   rU   osPathLiker   r   r   r   floatr-   r   r?   r   rE   rP   rM   rR   r	   r   rj   rv   r}   r   r   intr   __classcell__r2   r2   r0   r3   r       sV    	
W  6  r   )+r   r   r   r   pathlibr   r   typingr   r   r   r	   r
   r   r   r   rB   r'   r   r   	cloudpathr   enumsr   gspathr   google.auth.credentialsr   google.api_core.retryr   google.authr   r)   google.auth.exceptionsr   google.cloud.storager    ModuleNotFoundErrordependencies_loadedr   ImportErrorr   rS   r2   r2   r2   r3   <module>   s<    (  