
    hC                     @   S SK r S SKrS SKJrJr  S SKJrJrJrJ	r	J
r
JrJr  SSKJr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Jr  S SKJr  S SKJ r   S SK!r"\" S5       " S S\5      5       r%\%RL                  \%l        g! \# a    S\S   l$         N:f = f)    N)PathPurePosixPath)AnyCallableDictIterableOptionalTupleUnion   )Clientregister_client_class)implementation_registry)FileCacheMode)CloudPathException   )S3Path)Session)TransferConfig
S3Transfer)Config)ClientErrorFs3c                   R  ^  \ rS rSrSrSSSSSSSSSSS\R                  S4S\\   S\\   S\\   S\\	   S	\S
   S\\   S\S   S\\
\\4      S\\
\\R                  4      S\\   S\S   S\\   S\\   4U 4S jjjrS\S\\\4   4S jrS\S\
\\R                  4   S\4S jrS\S\\   4S jrS\S\	4S jrS\4S jrS*S\S\\\\	4      4S jjrS+S\S \S!\	S\4S" jjrS+S\S#\	SS4S$ jjrS\
\\R                  4   S\S\4S% jrS\S\4S& jr S,S\S'\!S\4S( jjr"S)r#U =r$$ )-S3Client   zClient class for AWS S3 which handles authentication with AWS for [`S3Path`](../s3path/)
instances. See documentation for the [`__init__` method][cloudpathlib.s3.s3client.S3Client.__init__]
for detailed authentication options.NFaws_access_key_idaws_secret_access_keyaws_session_tokenno_sign_requestbotocore_sessionzbotocore.session.Sessionprofile_nameboto3_sessionr   file_cache_modelocal_cache_direndpoint_urlboto3_transfer_configr   content_type_method
extra_argsc                   > U
=(       d    [         R                  " S5      n
Ub  Xpl        O[        UUUUUS9U l        U(       a  U R                  R	                  SU
[        [        R                  R                  S9S9U l	        U R                  R                  SU
[        [        R                  R                  S9S9U l
        O>U R                  R	                  SU
S9U l	        U R                  R                  SU
S9U l
        Xl        Uc  0 nXl        UR                  5        VVs0 s H  u  pU[        R                  ;   d  M  X_M     snnU l        UR                  5        VVs0 s H  u  pU[        R"                  ;   d  M  X_M     snnU l        S Vs0 s H#  nXR                  ;   d  M  XR                  U   _M%     snU l        Xl        [*        TU ]Y  U	UUS	9  gs  snnf s  snnf s  snf )
a  Class constructor. Sets up a boto3 [`Session`](
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html).
Directly supports the same authentication interface, as well as the same environment
variables supported by boto3. See [boto3 Session documentation](
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/session.html).

If no authentication arguments or environment variables are provided, then the client will
be instantiated as anonymous, which will only have access to public buckets.

Args:
    aws_access_key_id (Optional[str]): AWS access key ID.
    aws_secret_access_key (Optional[str]): AWS secret access key.
    aws_session_token (Optional[str]): Session key for your AWS account. This is only
        needed when you are using temporarycredentials.
    no_sign_request (Optional[bool]): If `True`, credentials are not looked for and we use unsigned
        requests to fetch resources. This will only allow access to public resources. This is equivalent
        to `--no-sign-request` in the [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/).
    botocore_session (Optional[botocore.session.Session]): An already instantiated botocore
        Session.
    profile_name (Optional[str]): Profile name of a profile in a shared credentials file.
    boto3_session (Optional[Session]): An already instantiated boto3 Session.
    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.
    endpoint_url (Optional[str]): S3 server endpoint URL to use for the constructed boto3 S3 resource and client.
        Parameterize it to access a customly deployed S3-compatible object store such as MinIO, Ceph or any other.
    boto3_transfer_config (Optional[dict]): Instantiated TransferConfig for managing
        [s3 transfers](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/s3.html#boto3.s3.transfer.TransferConfig)
    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).
    extra_args (Optional[dict]): A dictionary of extra args passed to download, upload, and list functions as relevant. You
        can include any keys supported by upload or download, and we will pass on only the relevant args. To see the extra
        args that are supported look at the upload and download lists in the
        [boto3 docs](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/s3.html#boto3.s3.transfer.S3Transfer).
AWS_ENDPOINT_URLN)r   r   r   r!   r"   r   signature_versionr&   config)r&   )RequestPayerExpectedBucketOwner)r%   r(   r$   )osgetenvsessr   resourcer   botocoresessionUNSIGNEDr   clientr'   _extra_argsitemsr   ALLOWED_DOWNLOAD_ARGSboto3_dl_extra_argsALLOWED_UPLOAD_ARGSboto3_ul_extra_argsboto3_list_extra_args_endpoint_urlsuper__init__)selfr   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   kv	__class__s                   R/home/james-whalen/.local/lib/python3.13/site-packages/cloudpathlib/s3/s3client.pyrC   S3Client.__init__   s   l $Dryy1C'D$%I"3&;"3!1)DI ii(()0@0@0I0IJ ) DG
 ))**)0@0@0I0IJ + DK ii((L(IDG))**4l*KDK%:"J%'--/$
/TQ1
8X8X3XDAD/$
  (--/$
/TQ1
8V8V3VDAD/$
  =&
<$$$ #A""<&
"
 *+ 3+ 	 	
!$
$
&
s$   %GG%G$G$G*-G*
cloud_pathreturnc                     U R                   R                  UR                  UR                  5      R                  " S0 U R
                  D6nUS   US   US   UR	                  SS 5      US   S.$ )NLastModifiedContentLengthETagContentTypeMetadata)last_modifiedsizeetagcontent_typeextra )r   ObjectSummarybucketkeygetr=   )rD   rJ   datas      rH   _get_metadataS3Client._get_metadata   st    ww$$Z%6%6
GKK 
&&

 ".1)L HH]D9*%
 	
    
local_pathc                     [        U5      nU R                  R                  UR                  UR                  5      nUR                  [        U5      U R                  U R                  S9  U$ )Nr   	ExtraArgs)	r   r   ObjectrY   rZ   download_filestrr'   r=   )rD   rJ   r`   objs       rH   _download_fileS3Client._download_file   s\    *%
ggnnZ..
?
OD$>$>$JbJb 	 	
 r_   c                 H    UR                   (       d  gU R                  U5      $ )Ndir)rZ   _s3_file_query)rD   rJ   s     rH   _is_file_or_dirS3Client._is_file_or_dir   s    ~~ "":..r_   c                 (   UR                   (       dZ  S Vs0 s H#  o"U R                  ;   d  M  X R                  U   _M%     nn U R                  R                  " SSUR                  0UD6  gU R                  U5      S L$ s  snf ! [
         a     gf = f)N)r1   BucketTFrW   )rZ   r:   r9   head_bucketrY   r   rl   )rD   rJ   rE   rV   s       rH   _existsS3Client._exists   s    ~~0G0G1PTP`P`K`&##A&&0G  ''Jz/@/@JEJ "":.d::  s   A?A?(B 
BBc           	          U R                   R                  " SUR                  UR                  R	                  S5      S.U R
                  D6  g! [        U R                   R                  R                  4 a    UR                  R	                  S5      S-   n[        S U R                  R                  UR                  5      R                  R                  " SSU0U R                  D6R                  S5       5       S5      s $ f = f)	zFBoto3 query used for quick checks of existence and if path is file/dir/rp   Keyfilec              3   &   #    U  H  nS v   M	     g7f)rk   NrW   ).0rg   s     rH   	<genexpr>*S3Client._s3_file_query.<locals>.<genexpr>   s      "  "s   Prefixr   NrW   )r9   head_objectrY   rZ   rstripr=   r   
exceptions	NoSuchKeynextr   rp   objectsfilterr@   limit)rD   rJ   rZ   s      rH   rl   S3Client._s3_file_query   s    	KK## !((NN))#. **
  T[[33==> 	..'',s2C z'8'89 ( R/2R6:6P6PRq" 
 
	s   AA B3DDc           
   #   T  ^ ^#    TR                   (       dP  U(       a  [        S5      eUU 4S jT R                  R                  5       R	                  S/ 5       5        S h  vN   g TR
                  nU(       a  UR                  S5      (       d  US-  n[        5       nT R                  R                  S5      nUR                  " STR                   UU(       a  SOSS.T R                  D6 GH3  nUR	                  S/ 5       Hk  nUR	                  S	5      R                  S5      nX;  d  M*  T R                  TR                   TR                    SU 35      S
4v   UR                  U5        Mm     UR	                  S/ 5       GH  n	U	R	                  S5      [        U5      S  n
[!        U
5      R"                   Hy  nU[%        U5      R                  S5      -   nX;  d  M'  [%        U5      S:w  d  M8  T R                  TR                   TR                    SU 35      S
4v   UR                  U5        M{     U	R	                  S5      R                  S5      nX;   a  M  U	R	                  S5      R                  S5      (       aY  U	R	                  S5      S:X  aD  T R                  TR                   TR                    SU 35      S
4v   UR                  U5        GMX  T R                  TR                   TR                    SU	R	                  S5       35      S4v   GM     GM6     g  GN7f)NztCannot recursively list all buckets and contents; you can get all the buckets then recursively list each separately.c              3   l   >#    U  H)  nTR                  TR                   US     35      S4v   M+     g7f)NameTN)	CloudPathcloud_prefix)rz   brJ   rD   s     rH   r{   %S3Client._list_dir.<locals>.<genexpr>   s:      FA :#:#:";AfI; GH$OFs   14Bucketsru   list_objects_v2 )rp   r}   	DelimiterCommonPrefixesr}   TContentsrw   .Sizer   FrW   )rY   NotImplementedErrorr9   list_bucketsr[   rZ   endswithsetget_paginatorpaginater@   r   r   r   addlenr   parentsrf   )rD   rJ   	recursiveprefixyielded_dirs	paginatorresultresult_prefix	canonical
result_keyo_relative_pathparentparent_canonicals   ``           rH   	_list_dirS3Client._list_dir   s      ) K 11377	2F   &//#..cMFuKK--.?@	(( 
$$&rC
 ((	
F "(,<b!A)--h7>>sC	0)667
8I8I7J!I;W 	  !$$Y/ "B %jjR8
",.."7F"F+O<DDF'-F0B0B30G'G$';Fs@R NN#-#:#:";J<M<M;NaP`Oa b !	  %(()9: E 'NN5188=	, >>%(11#66:>>&;QUV;V)667
8I8I7J!I;W 	  !$$Y/
 )667
8I8I7J!JNN[`LaKbc 	 ? 9'
s'   AL( L%!CL(,B0L( L(1D5L(srcdst
remove_srcc                 (   X:X  a  U R                   R                  UR                  UR                  5      nUR                  " SUR                  UR                  S.U R                  U5      R                  S0 5      SS.U R                  D6  U$ U R                   R                  UR                  UR                  5      nUR                  UR                  UR                  S.U R                  U R                  S9  U(       a  U R                  U5        U$ )Nrv   rV   REPLACE)
CopySourcerQ   MetadataDirective)rc   r   rW   )r   rd   rY   rZ   	copy_fromr]   r[   r?   copyr=   r'   _remove)rD   r   r   r   otargets         rH   
_move_fileS3Client._move_file"  s    :szz3773AKK &)jjA++C044WbA"+ **	" 
 WW^^CJJ8FKK::cgg62211   S!
r_   
missing_okc                    U R                  US9nUS:X  a  U R                  R                  UR                  UR                  5      R
                  " S0 U R                  D6nUR                  S5      R                  S5      S;  a  [        SU SU 35      eg US:X  a  U R                  R                  UR                  5      nUR                  nU(       a  UR                  S	5      (       d  US	-  nUR                  R                  " SS
U0U R                  D6R
                  " S0 U R                  D6nUS   R                  S5      R                  S5      S;  a  [        SU SU 35      eg U(       d  [        SU S35      eg )N)rJ   rx   ResponseMetadataHTTPStatusCode)      zDelete operation failed for z with response: rk   ru   r}   r   z(Cannot delete file that does not exist: z# (consider passing missing_ok=True)rW   )rm   r   rd   rY   rZ   deleter@   r[   r   rp   r   r   r   FileNotFoundError)rD   rJ   r   file_or_dirresprY   r   s          rH   r   S3Client._remove9  s   **j*A& 77>>*"3"3Z^^DKK ,,D xx*+//0@AS(2:,>NtfU  T
 E!WW^^J$5$56F^^Ffooc22#>>((UU$:T:TU\\ ,,D Aw{{-.223CDJV(2:,>NtfU  W '>zlJmn  r_   c                 P   U R                   R                  UR                  UR                  5      nU R                  R                  5       nU R                  b*  U R                  [        U5      5      u  pVUb  XTS'   Ub  XdS'   UR                  [        U5      U R                  US9  U$ )NrP   ContentEncodingrb   )
r   rd   rY   rZ   r?   r   r(   rf   upload_filer'   )rD   r`   rJ   rg   r)   rU   content_encodings          rH   _upload_fileS3Client._upload_fileZ  s    ggnnZ..
?--224
##/-1-E-Ec*o-V*L',8=)+0@,-J0J0JV`ar_   c                     [        [        R                  S9nU R                  R	                  SU R
                  US9nUR                  SUR                  UR                  S.SS9nU$ )zApparently the best way to get the public URL is to generate a presigned URL
with the unsigned config set. This creates a temporary unsigned client to generate
the correct URL
See: https://stackoverflow.com/a/48197877
r,   r   r.   
get_objectrv   r   Params	ExpiresIn)	r   r6   r8   r4   r9   rA   generate_presigned_urlrY   rZ   )rD   rJ   unsigned_configunsigned_clienturls        rH   _get_public_urlS3Client._get_public_urli  sp     !83D3DE))**t11/ + 
 #99(//
G : 

 
r_   expire_secondsc                 j    U R                   R                  SUR                  UR                  S.US9nU$ )Nr   rv   r   )r9   r   rY   rZ   )rD   rJ   r   r   s       rH   _generate_presigned_url S3Client._generate_presigned_urlz  s:    ;;55(//
G$ 6 

 
r_   )	rA   r:   r=   r@   r'   r?   r9   r   r4   )F)T)i  )%__name__
__module____qualname____firstlineno____doc__	mimetypes
guess_typer	   rf   boolr   r   r2   PathLiker   dictrC   r   r   r   r]   r   rh   rm   rr   rl   r   r
   r   r   r   r   r   intr   __static_attributes____classcell__)rG   s   @rH   r   r      s]   , ,0/3+/*/AE&*-1?C=A&*<@2;2F2F%)k
#C=k
  (}k
 $C=	k

 "$k
 ##=>k
 smk
  	*k
 "%](:";<k
 "%R[[(8"9:k
 smk
  ((89k
 &h/k
 TNk
 k
Z
 
4S> 
 U3CS=T Y] /& /Xc] /;& ;T ; 8MF MvW[|I\@] M^f 6 t v .& d d BuS"++-='> F W] & S "& # \_  r_   r   )'r   r2   pathlibr   r   typingr   r   r   r   r	   r
   r   r9   r   r   	cloudpathr   enumsr   r   r   s3pathr   boto3.sessionr   boto3.s3.transferr   r   botocore.configr   botocore.exceptionsr   botocore.sessionr6   ModuleNotFoundErrordependencies_loadedr   r   rW   r_   rH   <module>r      s     	 ' H H H 2 / ! + >%<&/
 tiv i iX $$c  >8=D!5>s   B
 
BB