U
    d/e9                    @  s  d Z ddlmZmZ ddlZddlZddlZddl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mZ dd	lmZ dd
lmZ ddlZddlZddlmZ ddlmZ ddlmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z< ddl=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQ ddlRmSZS ddlTmUZU ddlVmWZW ddlXmYZY ddlZm[Z[ ddl\m]Z] ddl^m_Z_m`Z` ddlambZbmcZc ddldmeZemfZf ddlgmhZh dd limjZj dd!lkmlZl dd"lmmnZnmoZompZpmqZqmrZrmsZs d#et  d$eu  d%e d&e ZvG d'd( d(ZwdS ))zQ
Simple Storage Service (aka S3) client to perform bucket and object operations.
    )absolute_importannotationsN)	timedelta)BytesIO)random)Thread)BinaryIOTextIO)
urlunsplit)ElementTree)PoolManager)HTTPHeaderDict   )	__title____version__time)COPYREPLACEComposeSource
CopySourceTags)StaticProvider)Provider)
CompleteMultipartUploadResultEventIterableListAllMyBucketsResultListMultipartUploadsResultListPartsResultObjectPart
PostPolicyparse_copy_objectparse_list_objects)DeleteErrorDeleteRequestDeleteResult)InvalidResponseErrorS3ErrorServerError)MAX_MULTIPART_COUNTMAX_MULTIPART_OBJECT_SIZEMAX_PART_SIZEMIN_PART_SIZEBaseURLObjectWriteResult
ThreadPoolcheck_bucket_namecheck_non_empty_string	check_sse
check_ssec
genheadersget_part_infoheaders_to_stringsis_valid_policy_typemakedirsmd5sum_hashread_part_datasha256_hashqueryencode)	LegalHold)LifecycleConfig)NotificationConfig)ObjectLockConfig)ReplicationConfig)	Retention)SelectObjectReaderSelectRequest)
presign_v4
sign_v4_s3)SseSseCustomerKey)	SSEConfig)Tagging)VersioningConfig)Element
SubElementfindtextgetbytesmarshal	unmarshalzMinIO (z; z) /c                   @  sx  e Zd ZU dZded< ded< ded< ded	< d
ed< ded< ddddddddd
dd	ddZdd ZdddZdd ZdddZ	ddd Z
d!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zdd7d8Zd9d: Zd;d< Zd=d> Zd?d@ ZdAdB ZdCdD ZdEdF ZdGdH ZdIdJ ZdKdL Z dMdN Z!dOdP Z"ddSdTZ#dUdV Z$dWdX Z%dd\d]Z&dd^d_Z'dddd`d`dadbddadcdd	dedfZ(ddgdhZ)didj Z*dkdl Z+ddmdnZ,dodp Z-dqdr Z.dsdt Z/ddudvZ0dwdx Z1dydz Z2dddd{d`ddad|d}d`d`d~ddddddZ3dddZ4dddZ5dddZ6dddZ7dddZ8e9ddddddfddZ:e9ddddddfddZ;e9ddfddZ<dd Z=dd Z>dd Z?dd Z@dd ZAdd ZBdd ZCdd ZDdd ZEdd ZFdddZGdddZHdddZIdddZJdddZKdddZLdd ZMdd ZNdd ZOdddZPdddZQdddZRdddÄZSdddńZTdddǄZUdS )Minioab  
    Simple Storage Service (aka S3) client to perform bucket and object
    operations.

    :param endpoint: Hostname of a S3 service.
    :param access_key: Access key (aka user ID) of your account in S3 service.
    :param secret_key: Secret Key (aka password) of your account in S3 service.
    :param session_token: Session token of your account in S3 service.
    :param secure: Flag to indicate to use secure (TLS) connection to S3
        service or not.
    :param region: Region name of buckets in S3 service.
    :param http_client: Customized HTTP client.
    :param credentials: Credentials provider of your account in S3 service.
    :param cert_check: Flag to indicate to verify SSL certificate or not.
    :return: :class:`Minio <Minio>` object

    Example::
        # Create client with anonymous access.
        client = Minio("play.min.io")

        # Create client with access and secret key.
        client = Minio("s3.amazonaws.com", "ACCESS-KEY", "SECRET-KEY")

        # Create client with access key and secret key with specific region.
        client = Minio(
            "play.minio.io:9000",
            access_key="Q3AM3UQ867SPQQA43P2F",
            secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
            region="my-region",
        )

    **NOTE on concurrent usage:** `Minio` object is thread safe when using
    the Python `threading` library. Specifically, it is **NOT** safe to share
    it between multiple processes, for example when using
    `multiprocessing.Pool`. The solution is simply to create a new `Minio`
    object in each process, and not share it between processes.

    zdict[str, str]_region_mapr-   	_base_urlstr_user_agentzTextIO | None_trace_streamzProvider | None	_providerr   _httpNTz
str | Noneboolzurllib3.PoolManager | None)	endpoint
access_key
secret_keysession_tokensecureregionhttp_clientcredentials
cert_checkc
                 C  s   |rt |tjjstdi | _t|r*dnd| || _t| _	d | _
|rTt|||}|| _tddj}
|ptjtjj|
|
dd|	rdnd	tjd
pt tjddddddgdd| _d S )NzCHTTP client should be instance of `urllib3.poolmanager.PoolManager`zhttps://zhttp://   )minutes)connectread
   CERT_REQUIRED	CERT_NONEZSSL_CERT_FILEg?i  i  i  i  )totalbackoff_factorstatus_forcelist)timeoutmaxsize	cert_reqsca_certsretries)
isinstanceurllib3poolmanagerr   
ValueErrorrT   r-   rU   _DEFAULT_USER_AGENTrW   rX   r   rY   r   secondsutilTimeoutosenvirongetcertifiwhereRetryrZ   )selfr\   r]   r^   r_   r`   ra   rb   rc   rd   ro    r   -/tmp/pip-unpacked-wheel-xery97c7/minio/api.py__init__~   s:    

zMinio.__init__c                 C  s   | j   d S )N)rZ   clearr   r   r   r   __del__   s    zMinio.__del__Fc                 C  sj   dddd |jd\}}|j d}|r:|r:|d| 7 }|rb|rb|dkrb|rb| j |rbd	\}}||fS )
zc
        Handle redirect response indicates whether retry HEAD request
        on failure.
        )ZPermanentRedirectzMoved Permanently)ZRedirectzTemporary redirect)Z
BadRequestzBad request)-  3    NNzx-amz-bucket-regionz; use region HEAD)	RetryHeadN)r~   statusheadersrT   )r   methodbucket_nameresponseretrycodemessagera   r   r   r   _handle_redirect_response   s,     
zMinio._handle_redirect_responsec           	      C  s   |pi }| d}||d< | j|d< d}d}|r@tt||d< |rl| jjrbd}|rXdnt|}q|t|}n|rtdnt|}|r||d< |r||d< |r|jr|j|d< t	
 }t	||d	< ||fS )
z$Build headers with given parameters.Content-MD5Hostz
User-AgentNzContent-LengthzUNSIGNED-PAYLOADx-amz-content-sha256X-Amz-Security-Tokenz
x-amz-date)r~   rW   rV   lenrU   Zis_httpsr9   r;   r_   r   utcnowZto_amz_date)	r   hostr   bodycredsZmd5sum_addedsha256Zmd5sumdater   r   r   _build_headers   s.    




zMinio._build_headersc
              
     s@  j rj  nd}
jj| |d}|j|||
\}}|
r^t||||
|d|}jrj	d |j
rd|j
 nd}j	 d|j | d j	t|d	d
 j	d |	s|dk	rj	d j	t|tr| nt| j	d j	d t |p(i  D ]<\}t|ttfr\fdd|D }n| q.jjt|||djrj	dj d j	tj j	d jdkrjr|rj	d j	j  j	d j	d S jd	d |s0  jrhdkrhjrhj	j  j	d dkrdjdddkrjrj	d jdkrȈjstdj jt jjdjrj ndjs,dkr,jrj	d t jjddjr>t!"nd}jrVj	d  fdd fdd fdddd  fdddd  fd dd!d d"}|s|j}|r| nd#\}}|stdj jt!|||jjd$jd% d&}|j#d'kr8j$% d |dS )(Execute HTTP request.Nr   object_namequery_paramsr   z---------START-HTTP---------
?  z
 HTTP/1.1
T)Z
titled_key
c                   s   g | ]}  |qS r   )add).0val)http_headerskeyr   r   
<listcomp>  s     z#Minio._url_open.<locals>.<listcomp>)r   r   preload_contentz	HTTP/1.1 )         z----------END-HTTP----------
)cache_contentr   application/xmlcontent-type;i0  z$server failed with HTTP status code c                     s     dS NTr   r   r   r   r   r   r   r   <lambda>^  s
      z!Minio._url_open.<locals>.<lambda>c                     s     dS r   r   r   r   r   r   r   a  s
      c                     s     dS r   r   r   r   r   r   r   d  s
      c                   S  s   dS )N)ZAccessDeniedzAccess deniedr   r   r   r   r   r   g      c                     s   rdS  rdS dS )N)Z	NoSuchKeyzObject does not existNoSuchBucketzBucket does not exist)ZResourceNotFoundzRequest resource not foundr   r   r   r   r   r   r   h  s
    c                   S  s   dS N)ZMethodNotAllowedz9The specified method is not allowed against this resourcer   r   r   r   r   r   o  r   c                     s    rdndfS )Nr   )ZResourceConflictzRequest resource conflictsr   r   )r   r   r   r   s  s    c                   S  s   dS r   r   r   r   r   r   r   x  r   )r   r   r   i  i  i  i  i  r   zx-amz-request-idz
x-amz-id-2r   )r   r   )&rY   retrieverU   buildr   netlocrF   r~   rX   writequerypathr6   rt   bytesdecoderV   r   itemslisttupler   rZ   urlopenr
   r   r   datarh   release_connsplitr(   r&   r'   fromxmlr   rT   pop)r   r   ra   r   r   r   r   r   r   no_body_tracer   urlr   r   value_Zresponse_errorZ	error_mapfuncr   r   r   )r   r   r   r   r   r   r   r   	_url_open   s    

 



!


zMinio._url_openc	                 C  s   |  |}	z| j||	|||||||d	W S  tk
rV }
 z|
jdkrF W 5 d}
~
X Y nX z| j||	|||||||d	W S  tk
r }
 z0|
jdkr | |||
j\}}|
||W 5 d}
~
X Y nX dS )r   )r   r   r   r   r   r   r   r   N)_get_regionr   r'   r   r   r   copy)r   r   r   r   r   r   r   r   r   ra   excr   r   r   r   r   _execute  sJ    


  zMinio._executec                 C  s   | j jr| j jS |r| jsdS | j|}|r2|S | jdd|ddid}t|j	 }|j
sdd}n|j
dkr|| j jr|d}n|j
}|| j|< |S )zg
        Return region of given bucket either from region cache or set in
        constructor.
        	us-east-1GETlocationr   )r   r   ZEUz	eu-west-1)rU   ra   rY   rT   r~   r   ET
fromstringr   r   textis_aws_host)r   r   ra   r   elementr   r   r   r     s*    

zMinio._get_regionc                 C  s*   |r|st dt d| d| | _dS )z
        Set your application name and version to user agent header.

        :param app_name: Application name.
        :param app_version: Application version.

        Example::
            client.set_app_info('my_app', '1.0.2')
        z)Application name/version cannot be empty.r   rR   N)rw   rx   rW   )r   Zapp_nameZapp_versionr   r   r   set_app_info  s    
zMinio.set_app_infoc                 C  s   |st d|| _dS )zb
        Enable http trace.

        :param stream: Stream for writing HTTP call tracing.
        z)Input stream for trace output is invalid.N)rw   rX   )r   streamr   r   r   trace_on  s    zMinio.trace_onc                 C  s
   d| _ dS )z%
        Disable HTTP trace.
        N)rX   r   r   r   r   	trace_off  s    zMinio.trace_offc                 C  s   d| j _dS )z3Enables accelerate endpoint for Amazon S3 endpoint.TNrU   Zaccelerate_host_flagr   r   r   r   enable_accelerate_endpoint  s    z Minio.enable_accelerate_endpointc                 C  s   d| j _dS )z4Disables accelerate endpoint for Amazon S3 endpoint.FNr   r   r   r   r   disable_accelerate_endpoint  s    z!Minio.disable_accelerate_endpointc                 C  s   d| j _dS )z2Enables dualstack endpoint for Amazon S3 endpoint.TNrU   Zdualstack_host_flagr   r   r   r   enable_dualstack_endpoint  s    zMinio.enable_dualstack_endpointc                 C  s   d| j _dS )z3Disables dualstack endpoint for Amazon S3 endpoint.FNr   r   r   r   r   disable_dualstack_endpoint  s    z Minio.disable_dualstack_endpointc                 C  s   d| j _dS )zEnables virtual style endpoint.TNrU   Zvirtual_style_flagr   r   r   r   enable_virtual_style_endpoint  s    z#Minio.enable_virtual_style_endpointc                 C  s   d| j _dS )z Disables virtual style endpoint.FNr   r   r   r   r   disable_virtual_style_endpoint   s    z$Minio.disable_virtual_style_endpointc              	   C  s`   t || jjd t| t|ts*tdt|}| jd|||dt	|iddddd	}t
|S )
aY  
        Select content of an object by SQL expression.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param request: :class:`SelectRequest <SelectRequest>` object.
        :return: A reader contains requested records and progress information.

        Example::
            with client.select_object_content(
                    "my-bucket",
                    "my-object.csv",
                    SelectRequest(
                        "select * from S3Object",
                        CSVInputSerialization(),
                        CSVOutputSerialization(),
                        request_progress=True,
                    ),
            ) as result:
                for data in result.stream():
                    print(data.decode())
                print(result.stats())
        Zs3_checkz"request must be SelectRequest typePOSTr   r   2)selectzselect-typeF)r   r   r   r   r   r   )r0   rU   r   r1   rt   rD   rw   rP   r   r9   rC   )r   r   r   requestr   r   r   r   r   select_object_content$  s    

	zMinio.select_object_contentc                 C  s   t |d| jjd | jjrB|rB| jj|krBtd| jj d| | jjpP|pPd}|r^ddind}d}|dkrtd	}t|d
| t|}| jd||||d || j	|< dS )aM  
        Create a bucket with region and object lock.

        :param bucket_name: Name of the bucket.
        :param location: Region in which the bucket will be created.
        :param object_lock: Flag to set object-lock feature.

        Examples::
            # Create bucket.
            client.make_bucket("my-bucket")

            # Create bucket on specific region.
            client.make_bucket("my-bucket", "us-west-1")

            # Create bucket with object-lock feature on specific region.
            client.make_bucket("my-bucket", "eu-west-2", object_lock=True)
        Tr   zregion must be z, but passed r   z x-amz-bucket-object-lock-enabledtrueNZCreateBucketConfigurationZLocationConstraintPUT)r   r   r   )
r0   rU   r   ra   rw   rL   rM   rO   r   rT   )r   r   r   Zobject_lockr   r   r   r   r   r   make_bucketL  s4    
zMinio.make_bucketc                 C  s    |  d}tt|j }|jS )a  
        List information of all accessible buckets.

        :return: List of :class:`Bucket <Bucket>` object.

        Example::
            buckets = client.list_buckets()
            for bucket in buckets:
                print(bucket.name, bucket.creation_date)
        r   )r   rQ   r   r   r   Zbuckets)r   r   resultr   r   r   list_buckets|  s    
zMinio.list_bucketsc              
   C  sV   t || jjd z| d| W dS  tk
rP } z|jdkr@ W 5 d}~X Y nX dS )a;  
        Check if a bucket exists.

        :param bucket_name: Name of the bucket.
        :return: True if the bucket exists.

        Example::
            if client.bucket_exists("my-bucket"):
                print("my-bucket exists")
            else:
                print("my-bucket does not exist")
        r   r   Tr   NFr0   rU   r   r   r'   r   r   r   r   r   r   r   bucket_exists  s    
zMinio.bucket_existsc                 C  s.   t || jjd | d| | j|d dS )z
        Remove an empty bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.remove_bucket("my-bucket")
        r   DELETEN)r0   rU   r   r   rT   r   r   r   r   r   r   remove_bucket  s    	zMinio.remove_bucketc                 C  s.   t || jjd | jd|ddid}|j S )z
        Get bucket policy configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: Bucket policy configuration as JSON string.

        Example::
            policy = client.get_bucket_policy("my-bucket")
        r   r   policyr   r   )r0   rU   r   r   r   r   r   r   r   r   r   r   get_bucket_policy  s    
  zMinio.get_bucket_policyc                 C  s(   t || jjd | jd|ddid dS )z
        Delete bucket policy configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_policy("my-bucket")
        r   r  r  r   r  Nr0   rU   r   r   r  r   r   r   delete_bucket_policy  s    	zMinio.delete_bucket_policyc                 C  s<   t || jjd t| | jd||dt|iddid dS )z
        Set bucket policy configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param policy: Bucket policy configuration as JSON string.

        Example::
            client.set_bucket_policy("my-bucket", policy)
        r   r   r   r  r   r   r   r   N)r0   rU   r   r7   r   r9   )r   r   r  r   r   r   set_bucket_policy  s    

zMinio.set_bucket_policyc                 C  s4   t || jjd | jd|ddid}tt|j S )a  
        Get notification configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`NotificationConfig <NotificationConfig>` object.

        Example::
            config = client.get_bucket_notification("my-bucket")
        r   r   notificationr   r  )r0   rU   r   r   rQ   r?   r   r   r  r   r   r   get_bucket_notification  s    
  zMinio.get_bucket_notificationc                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	a  
        Set notification configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :param config: class:`NotificationConfig <NotificationConfig>` object.

        Example::
            config = NotificationConfig(
                queue_config_list=[
                    QueueConfig(
                        "QUEUE-ARN-OF-THIS-BUCKET",
                        ["s3:ObjectCreated:*"],
                        config_id="1",
                        prefix_filter_rule=PrefixFilterRule("abc"),
                    ),
                ],
            )
            client.set_bucket_notification("my-bucket", config)
        r   z&config must be NotificationConfig typer   r   r  r   r
  N)	r0   rU   r   rt   r?   rw   rP   r   r9   r   r   configr   r   r   r   set_bucket_notification  s    

zMinio.set_bucket_notificationc                 C  s   |  |t  dS )a  
        Delete notification configuration of a bucket. On success, S3 service
        stops notification of events previously set of the bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_notification("my-bucket")
        N)r  r?   r  r   r   r   delete_bucket_notification  s    
z Minio.delete_bucket_notificationc                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	a5  
        Set encryption configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :param config: :class:`SSEConfig <SSEConfig>` object.

        Example::
            client.set_bucket_encryption(
                "my-bucket", SSEConfig(Rule.new_sse_s3_rule()),
            )
        r   zconfig must be SSEConfig typer   r   
encryptionr   r
  N)	r0   rU   r   rt   rI   rw   rP   r   r9   r  r   r   r   set_bucket_encryption  s    

zMinio.set_bucket_encryptionc              
   C  sj   t || jjd z&| jd|ddid}tt|j W S  tk
rd } z|j	dkrT W 5 d}~X Y nX dS )z
        Get encryption configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`SSEConfig <SSEConfig>` object.

        Example::
            config = client.get_bucket_encryption("my-bucket")
        r   r   r  r   r  .ServerSideEncryptionConfigurationNotFoundErrorN)
r0   rU   r   r   rQ   rI   r   r   r'   r   r   r   r   r   r   r   r   get_bucket_encryption3  s    

zMinio.get_bucket_encryptionc              
   C  s\   t || jjd z| jd|ddid W n. tk
rV } z|jdkrF W 5 d}~X Y nX dS )z
        Delete encryption configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_encryption("my-bucket")
        r   r  r  r   r  r  Nr   r   r   r   r   delete_bucket_encryptionJ  s    	

zMinio.delete_bucket_encryptionr   zs3:ObjectCreated:*zs3:ObjectRemoved:*zs3:ObjectAccessed:*c                   s8   t  jjd jjr tdt fddS )a  
        Listen events of object prefix and suffix of a bucket. Caller should
        iterate returned iterator to read new events.

        :param bucket_name: Name of the bucket.
        :param prefix: Listen events of object starts with prefix.
        :param suffix: Listen events of object ends with suffix.
        :param events: Events to listen.
        :return: Iterator of event records as :dict:.

        Example::
            with client.listen_bucket_notification(
                "my-bucket",
                prefix="my-prefix/",
                events=["s3:ObjectCreated:*", "s3:ObjectRemoved:*"],
            ) as events:
                for event in events:
                    print(event)
        r   z:ListenBucketNotification API is not supported in Amazon S3c                     s"   j d pdpddddS )Nr   r   )prefixsuffixeventsF)r   r   r   r   r   r  r  r   r  r   r   r   |  s   z2Minio.listen_bucket_notification.<locals>.<lambda>)r0   rU   r   rw   r   )r   r   r  r  r  r   r  r   listen_bucket_notification^  s    z Minio.listen_bucket_notificationc                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	a4  
        Set versioning configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param config: :class:`VersioningConfig <VersioningConfig>`.

        Example::
            client.set_bucket_versioning(
                "my-bucket", VersioningConfig(ENABLED),
            )
        r   z$config must be VersioningConfig typer   r   
versioningr   r
  N)	r0   rU   r   rt   rK   rw   rP   r   r9   r  r   r   r   set_bucket_versioning  s    

zMinio.set_bucket_versioningc                 C  s4   t || jjd | jd|ddid}tt|j S )a  
        Get versioning configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`VersioningConfig <VersioningConfig>`.

        Example::
            config = client.get_bucket_versioning("my-bucket")
            print(config.status)
        r   r   r  r   r  )r0   rU   r   r   rQ   rK   r   r   r  r   r   r   get_bucket_versioning  s    zMinio.get_bucket_versioningapplication/octet-streamr      c                 C  sR   t |j}t|d2}| j||||||||||	|
||dW  5 Q R  S Q R X dS )a  
        Uploads data from a file to an object in a bucket.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param file_path: Name of file to upload.
        :param content_type: Content type of the object.
        :param metadata: Any additional metadata to be uploaded along
            with your PUT request.
        :param sse: Server-side encryption.
        :param progress: A progress object
        :param part_size: Multipart part size
        :param num_parallel_uploads: Number of parallel uploads.
        :param tags: :class:`Tags` for the object.
        :param retention: :class:`Retention` configuration object.
        :param legal_hold: Flag to set legal hold for the object.
        :return: :class:`ObjectWriteResult` object.

        Example::
            # Upload data.
            result = client.fput_object(
                "my-bucket", "my-object", "my-filename",
            )

            # Upload data with metadata.
            result = client.fput_object(
                "my-bucket", "my-object", "my-filename",
                metadata={"My-Project": "one"},
            )

            # Upload data with tags, retention and legal-hold.
            date = datetime.utcnow().replace(
                hour=0, minute=0, second=0, microsecond=0,
            ) + timedelta(days=30)
            tags = Tags(for_object=True)
            tags["User"] = "jsmith"
            result = client.fput_object(
                "my-bucket", "my-object", "my-filename",
                tags=tags,
                retention=Retention(GOVERNANCE, date),
                legal_hold=True,
            )
        rb)	content_typemetadatasseprogress	part_sizenum_parallel_uploadstags	retention
legal_holdN)r|   statst_sizeopen
put_object)r   r   r   	file_pathr%  r&  r'  r(  r)  r*  r+  r,  r-  	file_sizeZ	file_datar   r   r   fput_object  s"    1        zMinio.fput_objectc
              	   C  sN  t || jjd t| |	r.t|	ts.tdtj	|rJt
d| dttj| | j||||d}
|p| dt|
j d}d}z| j||||||d	}|	rt|jd
d}|	j||d t|d0}|jddD ]}||}|	r|	| qW 5 Q R X tj|rt| t|| |
W S |rH|  |  X dS )a  
        Downloads data of an object to file.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param file_path: Name of file to download.
        :param request_headers: Any additional headers to be added with GET
                                request.
        :param ssec: Server-side encryption customer key.
        :param version_id: Version-ID of the object.
        :param extra_query_params: Extra query parameters for advanced usage.
        :param tmp_file_path: Path to a temporary file.
        :param progress: A progress object
        :return: Object information.

        Example::
            # Download data of an object.
            client.fget_object("my-bucket", "my-object", "my-filename")

            # Download data of an object of version-ID.
            client.fget_object(
                "my-bucket", "my-object", "my-filename",
                version_id="dfbd25b3-abec-4184-a4e8-5a35a5c1174d",
            )

            # Download data of an SSE-C encrypted object.
            client.fget_object(
                "my-bucket", "my-object", "my-filename",
                ssec=SseCustomerKey(b"32byteslongsecretkeymustprovided"),
            )
        r   *progress object must be instance of Threadzfile z is a directory)
version_id.z.part.minioN)request_headersssecr6  extra_query_paramscontent-lengthr   r   total_lengthwbi   )amt)r0   rU   r   r1   rt   r   	TypeErrorr|   r   isdirrw   r8   dirnamestat_objectr<   etagcloser   
get_objectintr   r~   set_metar0  r   r   updateexistsremoverename)r   r   r   r2  r8  r9  r6  r:  Ztmp_file_pathr(  r.  r   lengthZtmp_filer   sizer   r   r   fget_object  sP    "		

zMinio.fget_objectrG  zdict[str, str] | NonezSseCustomerKey | Nonezurllib3.BaseHTTPResponse)	r   r   offsetrM  r8  r9  r6  r:  returnc	                 C  s   t || jjd t| t| |r,| ni }	|	|p:i  |sF|rn|rV|| d nd}
d| d|
 |	d< |r|pxi }||d< | jd|||	|d	d
S )a  
        Get data of an object. Returned response should be closed after use to
        release network resources. To reuse the connection, it's required to
        call `response.release_conn()` explicitly.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param offset: Start byte position of object data.
        :param length: Number of bytes of object data from offset.
        :param request_headers: Any additional headers to be added with GET
                                request.
        :param ssec: Server-side encryption customer key.
        :param version_id: Version-ID of the object.
        :param extra_query_params: Extra query parameters for advanced usage.
        :return: :class:`urllib3.response.HTTPResponse` object.

        Example::
            # Get data of an object.
            try:
                response = client.get_object("my-bucket", "my-object")
                # Read data from response.
            finally:
                response.close()
                response.release_conn()

            # Get data of an object of version-ID.
            try:
                response = client.get_object(
                    "my-bucket", "my-object",
                    version_id="dfbd25b3-abec-4184-a4e8-5a35a5c1174d",
                )
                # Read data from response.
            finally:
                response.close()
                response.release_conn()

            # Get data of an object from offset and length.
            try:
                response = client.get_object(
                    "my-bucket", "my-object", offset=512, length=1024,
                )
                # Read data from response.
            finally:
                response.close()
                response.release_conn()

            # Get data of an SSE-C encrypted object.
            try:
                response = client.get_object(
                    "my-bucket", "my-object",
                    ssec=SseCustomerKey(b"32byteslongsecretkeymustprovided"),
                )
                # Read data from response.
            finally:
                response.close()
                response.release_conn()
        r   r   r   bytes=-ZRange	versionIdr   F)r   r   r   )r0   rU   r   r1   r3   r   rI  r   )r   r   r   rP  rM  r8  r9  r6  r:  r   endr   r   r   rF  E  s&    DzMinio.get_objectc              
   C  s  t || jjd t| t|ts*tdt| |dk	rLt|tsLtd|dk	rft|t	sftd|	dk	r|	t
tfkrtdt
 dt |
dk	r|
t
tfkrtdt
 dt d	}|jdkr|jdkr| j|j|j|j|jd
}|j}|jdk	s|jdk	s|tkrT|	t
kr"td|
t
kr4td| j||t||||||dS t|||||}|	rr|	|d< |
r|
|d< ||  | jd|||d}t|\}}t|||jd||j|dS )a  
        Create an object by server-side copying data from another object.
        In this API maximum supported source object size is 5GiB.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param source: :class:`CopySource` object.
        :param sse: Server-side encryption of destination object.
        :param metadata: Any user-defined metadata to be copied along with
                         destination object.
        :param tags: Tags for destination object.
        :param retention: :class:`Retention` configuration object.
        :param legal_hold: Flag to set legal hold for destination object.
        :param metadata_directive: Directive used to handle user metadata for
                                   destination object.
        :param tagging_directive: Directive used to handle tags for destination
                                   object.
        :return: :class:`ObjectWriteResult <ObjectWriteResult>` object.

        Example::
            # copy an object from a bucket to another.
            result = client.copy_object(
                "my-bucket",
                "my-object",
                CopySource("my-sourcebucket", "my-sourceobject"),
            )
            print(result.object_name, result.version_id)

            # copy an object with condition.
            result = client.copy_object(
                "my-bucket",
                "my-object",
                CopySource(
                    "my-sourcebucket",
                    "my-sourceobject",
                    modified_since=datetime(2014, 4, 1, tzinfo=timezone.utc),
                ),
            )
            print(result.object_name, result.version_id)

            # copy an object from a bucket with replacing metadata.
            metadata = {"test_meta_key": "test_meta_value"}
            result = client.copy_object(
                "my-bucket",
                "my-object",
                CopySource("my-sourcebucket", "my-sourceobject"),
                metadata=metadata,
                metadata_directive=REPLACE,
            )
            print(result.object_name, result.version_id)
        r   zsource must be CopySource typeNtags must be Tags type retention must be Retention typezmetadata directive must be z or ztagging directive must be r6  r9  zRCOPY metadata directive is not applicable to source object size greater than 5 GiBzQCOPY tagging directive is not applicable to source object size greater than 5 GiB)r'  r&  r+  r,  r-  zx-amz-metadata-directivezx-amz-tagging-directiver   )r   r   x-amz-version-id)last_modified) r0   rU   r   r1   rt   r   rw   r2   r   rB   r   r   rP  rM  rC  r   r   r6  r9  rN  r+   compose_objectr   ofr4   rI  Zgen_copy_headersr   r!   r.   r   r~   )r   r   r   sourcer'  r&  r+  r,  r-  metadata_directivetagging_directiverN  r.  r   r   rD  r[  r   r   r   copy_object  s    7




     
zMinio.copy_objectc           
   
   C  s  d}d}d}|D ]Z}|d7 }| j |j|j|j|jd}||j|j |j}|jdk	r`|j}n|j	dk	rt||j	8 }|t
k rt|dkr|t|krtd|j d|j d| dt
 ||7 }|tkrtd	t |tkrdt|t }||t  }	|	dkr|d7 }nt}	|	t
k rZt|dkrZ|t|krZtd|j d|j d
| dt
 ||7 }q|d7 }q|tkrtdt |S )zCalculate part count.r   r   rY  Nzsource rR   z: size z must be greater than z*destination object size must be less than z : for multipart split upload of z, last part size is less than z9Compose sources create more than allowed multipart count )rC  r   r   r6  r9  Zbuild_headersrN  rD  rM  rP  r,   r   rw   r*   r+   rG  r)   )
r   sourcesobject_size
part_countisrcr.  rN  countZlast_part_sizer   r   r   _calc_part_count!  sj    













zMinio._calc_part_countc                 C  s*   t ||d}| jd||||d}t|S )zExecute UploadPartCopy S3 API.Z
partNumberuploadIdr   r   r   )rV   r   r!   )r   r   r   	upload_idpart_numberr   r   r   r   r   r   _upload_part_copyb  s    zMinio._upload_part_copyc	                 C  s0  t || jjd t| t|ttfr*|s2tdd}	|D ]&}
t|
tsXtd|	 d|	d7 }	q:t	| |dk	rt|t
std|dk	rt|tstd	| |}|dkr|d jdkr|d jdkr| j||t|d ||||||rtnd|rtndd

S t|||||}| |||}t|tr>| ni }zd}g }|D ]h}
|
j}|
jdk	rr|
j}n|
jdk	r||
j8 }|
jpd}|
j}|| |tkr4|d7 }|
jdk	rd| d||
j d  |d< n(|
jdk	r
d| d|| d  |d< | |||||\}}|t|| qR|dkrR|d7 }|}|t }|tk rd|| }| }d| d| |d< | |||||\}}|t|| |}||| 8 }q4qR| ||||}t|j |j!|j"|j#|j$|j%dW S  t&k
r* } z|r| '||| |W 5 d}~X Y nX dS )ai  
        Create an object by combining data from different source objects using
        server-side copy.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param sources: List of :class:`ComposeSource` object.
        :param sse: Server-side encryption of destination object.
        :param metadata: Any user-defined metadata to be copied along with
                         destination object.
        :param tags: Tags for destination object.
        :param retention: :class:`Retention` configuration object.
        :param legal_hold: Flag to set legal hold for destination object.
        :return: :class:`ObjectWriteResult <ObjectWriteResult>` object.

        Example::
            sources = [
                ComposeSource("my-job-bucket", "my-object-part-one"),
                ComposeSource("my-job-bucket", "my-object-part-two"),
                ComposeSource("my-job-bucket", "my-object-part-three"),
            ]

            # Create my-bucket/my-object by combining source object
            # list.
            result = client.compose_object("my-bucket", "my-object", sources)
            print(result.object_name, result.version_id)

            # Create my-bucket/my-object with user metadata by combining
            # source object list.
            result = client.compose_object(
                "my-bucket",
                "my-object",
                sources,
                metadata={"test_meta_key": "test_meta_value"},
            )
            print(result.object_name, result.version_id)

            # Create my-bucket/my-object with user metadata and
            # server-side encryption by combining source object list.
            client.compose_object(
                "my-bucket", "my-object", sources, sse=SseS3(),
            )
            print(result.object_name, result.version_id)
        r   z,sources must be non-empty list or tuple typer   zsources[z] must be ComposeSource typer   NrV  rW  )r'  r&  r+  r,  r-  r_  r`  rR  rS  zx-amz-copy-source-ranger   )(r0   rU   r   r1   rt   r   r   rw   r   r2   r   rB   rh  rP  rM  ra  r   r]  r   r4   _create_multipart_uploadrH   r   rc  rI  r+   rn  appendr   r   _complete_multipart_uploadr.   r   r   r6  rD  r   r   	Exception_abort_multipart_upload)r   r   r   rb  r'  r&  r+  r,  r-  re  rf  rd  r   rl  Zssec_headersrm  Ztotal_partsrN  rP  rD  r   Zstart_bytesZ	end_bytesZheaders_copyr   r   r   r   r   r\  r  s    1


     
  





     zMinio.compose_objectc                 C  s   | j d||d|id dS )z$Execute AbortMultipartUpload S3 API.r  rj  r  Nr  )r   r   r   rl  r   r   r   rt  
  s    zMinio._abort_multipart_uploadc           
      C  sx   t d}|D ]6}t|d}t|dt|j t|dd|j d  qt|}| jd|||dt|dd	|id
}	t|	S )z'Execute CompleteMultipartUpload S3 API.ZCompleteMultipartUploadr   Z
PartNumberETag"r   r   )Content-Typer   rj  r
  )	rL   rM   rV   rm  rD  rO   r   r9   r   )
r   r   r   rl  partsr   parttagr   r   r   r   r   rr    s"    
z Minio._complete_multipart_uploadc                 C  sD   | dsd|d< | jd|||ddid}t|j }t|dS )z%Execute CreateMultipartUpload S3 API.rw  r"  r   uploadsr   rk  ZUploadId)r~   r   r   r   r   r   rN   )r   r   r   r   r   r   r   r   r   rp  *  s    
zMinio._create_multipart_uploadc              	   C  sB   | j d|||||dd}t|||jd|jddd|jS )zExecute PutObject S3 API.r   T)r   r   r   r   rZ  rD  rv  r   )r   r.   r   r~   replace)r   r   r   r   r   r   r   r   r   r   _put_object8  s     	
zMinio._put_objectc           	      C  s(   t ||d}| j|||||d}|jS )zExecute UploadPart S3 API.ri  r  )rV   r}  rD  )	r   r   r   r   r   rl  rm  r   r   r   r   r   _upload_partL  s        zMinio._upload_partc                 C  s   |d | j | fS )z Upload_part task for ThreadPool.re   )r~  )r   argsr   r   r   _upload_part_taskX  s    zMinio._upload_part_taskr   z
Sse | NonezThread | NonezTags | NonezRetention | Noner.   )r   r   r   rM  r%  r&  r'  r(  r)  r*  r+  r,  r-  rQ  c              
   C  s  t || jjd t| t| |dk	r:t|ts:td|dk	rTt|tsTtdt	t
|dsjtdt||	\}	}|rt|tstd|j||d t|||||}|pd	|d
< |}d}d}d}d}d}g }d}z|s<|d7 }|dkrB||kr
|| }	d}t||	|d}t||	krtd|	 dt| dnDt||	d ||d}t||	krn|}d}n|dd }|dd }|t|7 }|dkr| ||||W S |s| |||}|
r|
dkrt|
}|  |||t|tr| nd||f}|
dkr || j| q| j| }|t|| q|r| }dg| }| s|  \}}t||||d < qT| !||||}t"|j#|j$|j%|j&|j'|j(dW S  t)k
r } z|r| *||| |W 5 d}~X Y nX dS )a   
        Uploads data from a stream to an object in a bucket.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param data: An object having callable read() returning bytes object.
        :param length: Data size; -1 for unknown size and set valid part_size.
        :param content_type: Content type of the object.
        :param metadata: Any additional metadata to be uploaded along
            with your PUT request.
        :param sse: Server-side encryption.
        :param progress: A progress object;
        :param part_size: Multipart part size.
        :param num_parallel_uploads: Number of parallel uploads.
        :param tags: :class:`Tags` for the object.
        :param retention: :class:`Retention` configuration object.
        :param legal_hold: Flag to set legal hold for the object.
        :return: :class:`ObjectWriteResult` object.

        Example::
            # Upload data.
            result = client.put_object(
                "my-bucket", "my-object", io.BytesIO(b"hello"), 5,
            )

            # Upload data with metadata.
            result = client.put_object(
                "my-bucket", "my-object", io.BytesIO(b"hello"), 5,
                metadata={"My-Project": "one"},
            )

            # Upload data with tags, retention and legal-hold.
            date = datetime.utcnow().replace(
                hour=0, minute=0, second=0, microsecond=0,
            ) + timedelta(days=30)
            tags = Tags(for_object=True)
            tags["User"] = "jsmith"
            result = client.put_object(
                "my-bucket", "my-object", io.BytesIO(b"hello"), 5,
                tags=tags,
                retention=Retention(GOVERNANCE, date),
                legal_hold=True,
            )
        r   NrV  rW  rh   z$input data must have callable read()r5  r<  r"  rw  r   r   Fr   T)r(  z(stream having not enough data;expected: z, got: z bytesrX  ro  )+r0   rU   r   r1   r2   rt   r   rw   rB   callablegetattrr5   r   r@  rH  r4   r:   r   IOErrorr}  rp  r/   Zstart_parallelrH   r   Zadd_taskr  r~  rq  r   r   emptyr~   rr  r.   r   r   r6  rD  r   r   rs  rt  )r   r   r   r   rM  r%  r&  r'  r(  r)  r*  r+  r,  r-  rd  r   rc  Zuploaded_sizerm  Zone_bytestoprl  rx  poolZ	part_datar  rD  r   r   r   r   r   r1  \  s    <


     
        



     zMinio.put_objectc
           
      C  s,   | j ||rdnd||||||r"dnd|	d	S )a  
        Lists object information of a bucket.

        :param bucket_name: Name of the bucket.
        :param prefix: Object name starts with prefix.
        :param recursive: List recursively than directory structure emulation.
        :param start_after: List objects after this key name.
        :param include_user_meta: MinIO specific flag to control to include
                                 user metadata.
        :param include_version: Flag to control whether include object
                                versions.
        :param use_api_v1: Flag to control to use ListObjectV1 S3 API or not.
        :param use_url_encoding_type: Flag to control whether URL encoding type
                                      to be used or not.
        :return: Iterator of :class:`Object <Object>`.

        Example::
            # List objects information.
            objects = client.list_objects("my-bucket")
            for obj in objects:
                print(obj)

            # List objects information whose names starts with "my/prefix/".
            objects = client.list_objects("my-bucket", prefix="my/prefix/")
            for obj in objects:
                print(obj)

            # List objects information recursively.
            objects = client.list_objects("my-bucket", recursive=True)
            for obj in objects:
                print(obj)

            # List objects information recursively whose names starts with
            # "my/prefix/".
            objects = client.list_objects(
                "my-bucket", prefix="my/prefix/", recursive=True,
            )
            for obj in objects:
                print(obj)

            # List objects information recursively after object name
            # "my/prefix/world/1".
            objects = client.list_objects(
                "my-bucket", recursive=True, start_after="my/prefix/world/1",
            )
            for obj in objects:
                print(obj)
        NrR   r   )	delimiterinclude_user_metar  start_after
use_api_v1include_versionencoding_typefetch_owner)_list_objects)
r   r   r  	recursiver  r  r  r  Zuse_url_encoding_typer  r   r   r   list_objects  s    4

zMinio.list_objectsc           
      C  s   t || jjd t| t| |r,| ni }|p6i }||rHd|ini  | jd||||d}|jd}	|	r|t	
|	}	t|||	|jddddt|jd	d
|jd|j|jddS )a  
        Get object information and metadata of an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param ssec: Server-side encryption customer key.
        :param version_id: Version ID of the object.
        :param extra_query_params: Extra query parameters for advanced usage.
        :return: :class:`Object <Object>`.

        Example::
            # Get object information.
            result = client.stat_object("my-bucket", "my-object")

            # Get object information of version-ID.
            result = client.stat_object(
                "my-bucket", "my-object",
                version_id="dfbd25b3-abec-4184-a4e8-5a35a5c1174d",
            )

            # Get SSE-C encrypted object information.
            result = client.stat_object(
                "my-bucket", "my-object",
                ssec=SseCustomerKey(b"32byteslongsecretkeymustprovided"),
            )
        r   rT  r   rk  zlast-modifiedrD  r   rv  r;  0r   rZ  )r[  rD  rN  r%  r&  r6  )r0   rU   r   r1   r3   r   rI  r   r~   r   Zfrom_http_headerr   r|  rG  )
r   r   r   r9  r6  r:  r   r   r   r[  r   r   r   rC  D  s4    


zMinio.stat_objectc                 C  s:   t || jjd t| | jd|||r.d|indd dS )a  
        Remove an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.

        Example::
            # Remove object.
            client.remove_object("my-bucket", "my-object")

            # Remove version of an object.
            client.remove_object(
                "my-bucket", "my-object",
                version_id="dfbd25b3-abec-4184-a4e8-5a35a5c1174d",
            )
        r   r  rT  Nr  r0   rU   r   r1   r   )r   r   r   r6  r   r   r   remove_object  s    zMinio.remove_objectc           	      C  s~   t t||d}dt|i}|r(d|d< | jd|||ddid}t|j }|j	d	rnt
g t|gS tt
|j S )
au  
        Delete multiple objects.

        :param bucket_name: Name of the bucket.
        :param delete_object_list: List of maximum 1000
            :class:`DeleteObject <DeleteObject>` object.
        :param quiet: quiet flag.
        :param bypass_governance_mode: Bypass Governance retention mode.
        :return: :class:`DeleteResult <DeleteResult>` object.
        )quietr   r   z!x-amz-bypass-governance-retentionr   deleter   r
  Error)rP   r$   r9   r   r   r   r   r   rz  endswithr%   r#   r   rQ   )	r   r   delete_object_listr  bypass_governance_moder   r   r   r   r   r   r   _delete_objects  s     
zMinio._delete_objectsc                 c  sl   t || jjd t|}dd ttd|D }|s8qh| j||d|d}|jD ]}|j	dkrP|V  qPqdS )	a  
        Remove multiple objects.

        :param bucket_name: Name of the bucket.
        :param delete_object_list: An iterable containing
            :class:`DeleteObject <DeleteObject>` object.
        :param bypass_governance_mode: Bypass Governance retention mode.
        :return: An iterator containing :class:`DeleteError <DeleteError>`
            object.

        Example::
            # Remove list of objects.
            errors = client.remove_objects(
                "my-bucket",
                [
                    DeleteObject("my-object1"),
                    DeleteObject("my-object2"),
                    DeleteObject(
                        "my-object3", "13f88b18-8dcd-4c83-88f2-8631fdb6250c",
                    ),
                ],
            )
            for error in errors:
                print("error occurred when deleting object", error)

            # Remove a prefix recursively.
            delete_object_list = map(
                lambda x: DeleteObject(x.object_name),
                client.list_objects("my-bucket", "my/prefix/", recursive=True),
            )
            errors = client.remove_objects("my-bucket", delete_object_list)
            for error in errors:
                print("error occurred when deleting object", error)
        r   c                 S  s   g | ]\}}|qS r   r   )r   r   Zdelete_objectr   r   r   r     s    z(Minio.remove_objects.<locals>.<listcomp>  T)r  r  ZNoSuchVersionN)
r0   rU   r   	itertoolschainzipranger  Z
error_listr   )r   r   r  r  objectsr   errorr   r   r   remove_objects  s&    $
 

zMinio.remove_objects   )daysc	              	   C  s   t || jjd t| | dk s0| dkr8td| |}	|pHi }
|
|rZd|ini  |
|pji  | jr~| j	 nd}|r|j
r|j
|
d< | jj||	|||
d}|rt|||	||pt t| }t|S )	a  
        Get presigned URL of an object for HTTP method, expiry time and custom
        request parameters.

        :param method: HTTP method.
        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param expires: Expiry in seconds; defaults to 7 days.
        :param response_headers: Optional response_headers argument to
                                 specify response fields like date, size,
                                 type of file, data about server, etc.
        :param request_date: Optional request_date argument to
                             specify a different request date. Default is
                             current date.
        :param version_id: Version ID of the object.
        :param extra_query_params: Extra query parameters for advanced usage.
        :return: URL string.

        Example::
            # Get presigned URL string to delete 'my-object' in
            # 'my-bucket' with one day expiry.
            url = client.get_presigned_url(
                "DELETE",
                "my-bucket",
                "my-object",
                expires=timedelta(days=1),
            )
            print(url)
        r   r   i:	 z*expires must be between 1 second to 7 daysrT  Nr   r   )r0   rU   r   r1   total_secondsrw   r   rI  rY   r   r_   r   rE   r   r   rG  r
   )r   r   r   r   expiresresponse_headersrequest_dater6  r:  ra   r   r   r   r   r   r   get_presigned_url  s8    !




zMinio.get_presigned_urlc              
   C  s   | j d|||||||dS )aS  
        Get presigned URL of an object to download its data with expiry time
        and custom request parameters.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param expires: Expiry in seconds; defaults to 7 days.
        :param response_headers: Optional response_headers argument to
                                  specify response fields like date, size,
                                  type of file, data about server, etc.
        :param request_date: Optional request_date argument to
                              specify a different request date. Default is
                              current date.
        :param version_id: Version ID of the object.
        :param extra_query_params: Extra query parameters for advanced usage.
        :return: URL string.

        Example::
            # Get presigned URL string to download 'my-object' in
            # 'my-bucket' with default expiry (i.e. 7 days).
            url = client.presigned_get_object("my-bucket", "my-object")
            print(url)

            # Get presigned URL string to download 'my-object' in
            # 'my-bucket' with two hours expiry.
            url = client.presigned_get_object(
                "my-bucket", "my-object", expires=timedelta(hours=2),
            )
            print(url)
        r   )r  r  r6  r:  r  )r   r   r   r  r  r  r6  r:  r   r   r   presigned_get_object;  s    $zMinio.presigned_get_objectc                 C  s   |  d|||S )aF  
        Get presigned URL of an object to upload data with expiry time and
        custom request parameters.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param expires: Expiry in seconds; defaults to 7 days.
        :return: URL string.

        Example::
            # Get presigned URL string to upload data to 'my-object' in
            # 'my-bucket' with default expiry (i.e. 7 days).
            url = client.presigned_put_object("my-bucket", "my-object")
            print(url)

            # Get presigned URL string to upload data to 'my-object' in
            # 'my-bucket' with two hours expiry.
            url = client.presigned_put_object(
                "my-bucket", "my-object", expires=timedelta(hours=2),
            )
            print(url)
        r   r  )r   r   r   r  r   r   r   presigned_put_objectj  s       zMinio.presigned_put_objectc                 C  sL   t |tstd| js tdt|j| jjd || j	 | 
|jS )aK  
        Get form-data of PostPolicy of an object to upload its data using POST
        method.

        :param policy: :class:`PostPolicy <PostPolicy>`.
        :return: :dict: contains form-data.

        Example::
            policy = PostPolicy(
                "my-bucket", datetime.utcnow() + timedelta(days=10),
            )
            policy.add_starts_with_condition("key", "my/object/prefix/")
            policy.add_content_length_range_condition(
                1*1024*1024, 10*1024*1024,
            )
            form_data = client.presigned_post_policy(policy)
        zpolicy must be PostPolicy typez:anonymous access does not require presigned post form-datar   )rt   r    rw   rY   r0   r   rU   r   Z	form_datar   r   )r   r  r   r   r   presigned_post_policy  s    
 
zMinio.presigned_post_policyc                 C  s(   t || jjd | jd|ddid dS )z
        Delete replication configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_replication("my-bucket")
        r   r  replicationr   r  Nr  r  r   r   r   delete_bucket_replication  s    	zMinio.delete_bucket_replicationc              
   C  sj   t || jjd z&| jd|ddid}tt|j W S  tk
rd } z|j	dkrT W 5 d}~X Y nX dS )a  
        Get bucket replication configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`ReplicationConfig <ReplicationConfig>` object.

        Example::
            config = client.get_bucket_replication("my-bucket")
        r   r   r  r   r  Z%ReplicationConfigurationNotFoundErrorN)
r0   rU   r   r   rQ   rA   r   r   r'   r   r  r   r   r   get_bucket_replication  s    
  
zMinio.get_bucket_replicationc                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	aP  
        Set bucket replication configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param config: :class:`ReplicationConfig <ReplicationConfig>` object.

        Example::
            config = ReplicationConfig(
                "REPLACE-WITH-ACTUAL-ROLE",
                [
                    Rule(
                        Destination(
                            "REPLACE-WITH-ACTUAL-DESTINATION-BUCKET-ARN",
                        ),
                        ENABLED,
                        delete_marker_replication=DeleteMarkerReplication(
                            DISABLED,
                        ),
                        rule_filter=Filter(
                            AndOperator(
                                "TaxDocs",
                                {"key1": "value1", "key2": "value2"},
                            ),
                        ),
                        rule_id="rule1",
                        priority=1,
                    ),
                ],
            )
            client.set_bucket_replication("my-bucket", config)
        r   z%config must be ReplicationConfig typer   r   r  r   r
  N)	r0   rU   r   rt   rA   rw   rP   r   r9   r  r   r   r   set_bucket_replication  s     

zMinio.set_bucket_replicationc                 C  s(   t || jjd | jd|ddid dS )z
        Delete notification configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_lifecycle("my-bucket")
        r   r  	lifecycler   r  Nr  r  r   r   r   delete_bucket_lifecycle  s    	zMinio.delete_bucket_lifecyclec              
   C  sj   t || jjd z&| jd|ddid}tt|j W S  tk
rd } z|j	dkrT W 5 d}~X Y nX dS )a  
        Get bucket lifecycle configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`LifecycleConfig <LifecycleConfig>` object.

        Example::
            config = client.get_bucket_lifecycle("my-bucket")
        r   r   r  r   r  ZNoSuchLifecycleConfigurationN)
r0   rU   r   r   rQ   r>   r   r   r'   r   r  r   r   r   get_bucket_lifecycle  s    
  
zMinio.get_bucket_lifecyclec                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	a  
        Set bucket lifecycle configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param config: :class:`LifecycleConfig <LifecycleConfig>` object.

        Example::
            config = LifecycleConfig(
                [
                    Rule(
                        ENABLED,
                        rule_filter=Filter(prefix="documents/"),
                        rule_id="rule1",
                        transition=Transition(
                            days=30, storage_class="GLACIER",
                        ),
                    ),
                    Rule(
                        ENABLED,
                        rule_filter=Filter(prefix="logs/"),
                        rule_id="rule2",
                        expiration=Expiration(days=365),
                    ),
                ],
            )
            client.set_bucket_lifecycle("my-bucket", config)
        r   z#config must be LifecycleConfig typer   r   r  r   r
  N)	r0   rU   r   rt   r>   rw   rP   r   r9   r  r   r   r   set_bucket_lifecycle	  s    

zMinio.set_bucket_lifecyclec                 C  s(   t || jjd | jd|ddid dS )z
        Delete tags configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_bucket_tags("my-bucket")
        r   r  taggingr   r  Nr  r  r   r   r   delete_bucket_tags;	  s    	zMinio.delete_bucket_tagsc              
   C  sp   t || jjd z,| jd|ddid}tt|j }|jW S  t	k
rj } z|j
dkrZ W 5 d}~X Y nX dS )z
        Get tags configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`Tags <Tags>` object.

        Example::
            tags = client.get_bucket_tags("my-bucket")
        r   r   r  r   r  NoSuchTagSetN)r0   rU   r   r   rQ   rJ   r   r   r+  r'   r   )r   r   r   r  r   r   r   r   get_bucket_tagsG	  s    
  
zMinio.get_bucket_tagsc                 C  sR   t || jjd t|ts"tdtt|}| jd||dt	|iddid dS )	a[  
        Set tags configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param tags: :class:`Tags <Tags>` object.

        Example::
            tags = Tags.new_bucket_tags()
            tags["Project"] = "Project One"
            tags["User"] = "jsmith"
            client.set_bucket_tags("my-bucket", tags)
        r   rV  r   r   r  r   r
  N)
r0   rU   r   rt   r   rw   rP   rJ   r   r9   )r   r   r+  r   r   r   r   set_bucket_tags]	  s    

zMinio.set_bucket_tagsc                 C  sF   t || jjd t| |r$d|ini }d|d< | jd|||d dS )a)  
        Delete tags configuration of an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the Object.

        Example::
            client.delete_object_tags("my-bucket", "my-object")
        r   rT  r   r  r  r   r   Nr  )r   r   r   r6  r   r   r   r   delete_object_tagsv	  s    zMinio.delete_object_tagsc              
   C  s   t || jjd t| |r$d|ini }d|d< z*| jd|||d}tt|j }|j	W S  t
k
r } z|jdkrx W 5 d}~X Y nX dS )	aW  
        Get tags configuration of a object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the Object.
        :return: :class:`Tags <Tags>` object.

        Example::
            tags = client.get_object_tags("my-bucket", "my-object")
        r   rT  r   r  r   r  r  N)r0   rU   r   r1   r   rQ   rJ   r   r   r+  r'   r   )r   r   r   r6  r   r   r  r   r   r   r   get_object_tags	  s"    
zMinio.get_object_tagsc                 C  sp   t || jjd t| t|ts*tdtt|}|rBd|ini }d|d< | j	d|||dt
|i|d d	S )
a  
        Set tags configuration to an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the Object.
        :param tags: :class:`Tags <Tags>` object.

        Example::
            tags = Tags.new_object_tags()
            tags["Project"] = "Project One"
            tags["User"] = "jsmith"
            client.set_object_tags("my-bucket", "my-object", tags)
        r   rV  rT  r   r  r   r   r   r   r   r   N)r0   rU   r   r1   rt   r   rw   rP   rJ   r   r9   )r   r   r   r+  r6  r   r   r   r   r   set_object_tags	  s    

zMinio.set_object_tagsc                 C  s^   t || jjd t| ttd}|r0d|ini }d|d< | jd|||dt|i|d d	S )
a'  
        Enable legal hold on an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.

        Example::
            client.enable_object_legal_hold("my-bucket", "my-object")
        r   TrT  r   
legal-holdr   r   r  Nr0   rU   r   r1   rP   r=   r   r9   r   r   r   r6  r   r   r   r   r   enable_object_legal_hold	  s    
zMinio.enable_object_legal_holdc                 C  s^   t || jjd t| ttd}|r0d|ini }d|d< | jd|||dt|i|d d	S )
a)  
        Disable legal hold on an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.

        Example::
            client.disable_object_legal_hold("my-bucket", "my-object")
        r   FrT  r   r  r   r   r  Nr  r  r   r   r   disable_object_legal_hold	  s    
zMinio.disable_object_legal_holdc              
   C  s   t || jjd t| |r$d|ini }d|d< z*| jd|||d}tt|j }|j	W S  t
k
r } z|jdkrx W 5 d}~X Y nX d	S )
a  
        Returns true if legal hold is enabled on an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.

        Example::
            if client.is_object_legal_hold_enabled("my-bucket", "my-object"):
                print("legal hold is enabled on my-object")
            else:
                print("legal hold is not enabled on my-object")
        r   rT  r   r  r   r  NoSuchObjectLockConfigurationNF)r0   rU   r   r1   r   rQ   r=   r   r   r   r'   r   )r   r   r   r6  r   r   r-  r   r   r   r   is_object_legal_hold_enabled	  s"    
z"Minio.is_object_legal_hold_enabledc                 C  s   |  |tddd dS )z
        Delete object-lock configuration of a bucket.

        :param bucket_name: Name of the bucket.

        Example::
            client.delete_object_lock_config("my-bucket")
        N)set_object_lock_configr@   r  r   r   r   delete_object_lock_config!
  s    	 
zMinio.delete_object_lock_configc                 C  s4   t || jjd | jd|ddid}tt|j S )a  
        Get object-lock configuration of a bucket.

        :param bucket_name: Name of the bucket.
        :return: :class:`ObjectLockConfig <ObjectLockConfig>` object.

        Example::
            config = client.get_object_lock_config("my-bucket")
        r   r   object-lockr   r  )r0   rU   r   r   rQ   r@   r   r   r  r   r   r   get_object_lock_config.
  s    
  zMinio.get_object_lock_configc                 C  sN   t || jjd t|ts"tdt|}| jd||dt|iddid dS )	aG  
        Set object-lock configuration to a bucket.

        :param bucket_name: Name of the bucket.
        :param config: :class:`ObjectLockConfig <ObjectLockConfig>` object.

        Example::
            config = ObjectLockConfig(GOVERNANCE, 15, DAYS)
            client.set_object_lock_config("my-bucket", config)
        r   z$config must be ObjectLockConfig typer   r   r  r   r
  N)	r0   rU   r   rt   r@   rw   rP   r   r9   r  r   r   r   r  >
  s    

zMinio.set_object_lock_configc              
   C  s   t || jjd t| |r$d|ini }d|d< z$| jd|||d}tt|j W S  t	k
r } z|j
dkrr W 5 d}~X Y nX dS )	an  
        Get retention configuration of an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.
        :return: :class:`Retention <Retention>` object.

        Example::
            config = client.get_object_retention("my-bucket", "my-object")
        r   rT  r   r,  r   r  r  N)r0   rU   r   r1   r   rQ   rB   r   r   r'   r   )r   r   r   r6  r   r   r   r   r   r   get_object_retentionU
  s     
zMinio.get_object_retentionc                 C  sl   t || jjd t| t|ts*tdt|}|r>d|ini }d|d< | jd|||dt	|i|d d	S )
a  
        Set retention configuration on an object.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param version_id: Version ID of the object.
        :param config: :class:`Retention <Retention>` object.

        Example::
            config = Retention(
                GOVERNANCE, datetime.utcnow() + timedelta(days=10),
            )
            client.set_object_retention("my-bucket", "my-object", config)
        r   zconfig must be Retention typerT  r   r,  r   r   r  N)
r0   rU   r   r1   rt   rB   rw   rP   r   r9   )r   r   r   r  r6  r   r   r   r   r   set_object_retentiont
  s    

zMinio.set_object_retentionc
                 C  s0  t || jjd dt  d}
t|}|p.i }d|d< |}|	rDdnd}|rPdnt }tj|||d	`}|D ]T}|j	r|
|j	|j qlt|j}|j|_t|jpt |_|||j qlW 5 Q R X |s| }|d
 nt|j}|r| j||
|||||||d	S | j||
||||||||d
S )a  
        Uploads multiple objects in a single put call. It is done by creating
        intermediate TAR file optionally compressed which is uploaded to S3
        service.

        :param bucket_name: Name of the bucket.
        :param object_list: An iterable containing
            :class:`SnowballObject <SnowballObject>` object.
        :param metadata: Any additional metadata to be uploaded along
            with your PUT request.
        :param sse: Server-side encryption.
        :param tags: :class:`Tags` for the object.
        :param retention: :class:`Retention` configuration object.
        :param legal_hold: Flag to set legal hold for the object.
        :param staging_filename: A staging filename to create intermediate
            tarball.
        :param compression: Flag to compress TAR ball.
        :return: :class:`ObjectWriteResult` object.

        Example::
            # Upload snowball object.
            result = client.upload_snowball_objects(
                "my-bucket",
                [
                    SnowballObject("my-object1", filename="/etc/hostname"),
                    SnowballObject(
                        "my-object2", data=io.BytesIO("hello"), length=5,
                    ),
                    SnowballObject(
                        "my-object3", data=io.BytesIO("world"), length=5,
                        mod_time=datetime.now(),
                    ),
                ],
            )
        r   z	snowball.z.tarr   z X-Amz-Meta-Snowball-Auto-Extractzw:gzwN)namemodefileobjr   )r&  r'  r+  r,  r-  r)  )r0   rU   r   r   r  r  r   tarfiler0  filenamer   r   TarInforM  rN  r   Zto_floatZmod_timer   mtimeaddfiler   tellseekr|   r.  r/  r4  r1  )r   r   Zobject_listr&  r'  r+  r,  r-  Zstaging_filenamecompressionr   r  r  r  tarobjinforM  r   r   r   upload_snowball_objects
  sL    '

   
    zMinio.upload_snowball_objectsc                 c  s   t || jjd |
rd}d}|ri }|r4d|d< n|s@d|d< |sl|sl|rT||d< |r`d|d	< |rld|d
< |prd|d< |r||d< t|pd|d< |pd|d< |	r|r|	|d< n|r|	|d< n|	|d< |
r|
|d< | jd||d}t|\}}}	}
|sd}
|s|	}|D ]}|V  qqdS )a6  
        List objects optionally including versions.
        Note: Its required to send empty values to delimiter/prefix and 1000 to
        max-keys when not provided for server-side bucket policy evaluation to
        succeed; otherwise AccessDenied error will be returned for such
        policies.
        r   Tr   versionsr   z	list-typezcontinuation-tokenr   zfetch-ownerr&  r  encoding-typer  zmax-keysr  
key-markermarkerzstart-afterzversion-id-markerr   r  N)r0   rU   r   rV   r   r"   )r   r   Zcontinuation_tokenr  r  r  r  Zmax_keysr  r  Zversion_id_markerr  r  Zis_truncatedr   r   r  r  r   r   r   r  
  sN    



zMinio._list_objectsc
                 C  sl   |	pi }
|
 d|pdt|pd|p$ddd |r:||
d< |rF||
d< |rR||
d< | jd||
|d	}t|S )
a  
        Execute ListMultipartUploads S3 API.

        :param bucket_name: Name of the bucket.
        :param delimiter: (Optional) Delimiter on listing.
        :param encoding_type: (Optional) Encoding type.
        :param key_marker: (Optional) Key marker.
        :param max_uploads: (Optional) Maximum upload information to fetch.
        :param prefix: (Optional) Prefix on listing.
        :param upload_id_marker: (Optional) Upload ID marker.
        :param extra_headers: (Optional) Extra headers for advanced usage.
        :param extra_query_params: (Optional) Extra query parameters for
            advanced usage.
        :return:
            :class:`ListMultipartUploadsResult <ListMultipartUploadsResult>`
                object
        r   r  r   )r{  r  zmax-uploadsr  r  r  r  zupload-id-markerr   )r   r   )rI  rV   r   r   )r   r   r  r  Z
key_markerZmax_uploadsr  Zupload_id_markerextra_headersr:  r   r   r   r   r   _list_multipart_uploads+  s,    
	zMinio._list_multipart_uploadsc           
      C  sH   |pi }| |t|pdd |r,||d< | jd||||d}	t|	S )a6  
        Execute ListParts S3 API.

        :param bucket_name: Name of the bucket.
        :param object_name: Object name in the bucket.
        :param upload_id: Upload ID.
        :param max_parts: (Optional) Maximum parts information to fetch.
        :param part_number_marker: (Optional) Part number marker.
        :param extra_headers: (Optional) Extra headers for advanced usage.
        :param extra_query_params: (Optional) Extra query parameters for
            advanced usage.
        :return: :class:`ListPartsResult <ListPartsResult>` object
        r  )rj  z	max-partszpart-number-markerr   )r   r   r   )rI  rV   r   r   )
r   r   r   rl  Z	max_partsZpart_number_markerr  r:  r   r   r   r   r   _list_parts[  s     
zMinio._list_parts)NNNTNNNT)F)NNNNNTF)NNNNNTF)NF)r   r   r  )	r"  NNNr   r#  NNF)NNNNNN)r   r   NNNN)NNNNFNN)NNNNF)N)	r"  NNNr   r#  NNF)NFNFFFTF)NNN)N)FF)F)N)N)N)N)N)N)N)N)NNNNFNF)NNNNNNNNNFF)NNNNNNNN)NNNN)V__name__
__module____qualname____doc____annotations__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r  r  r  r  r  r   r!  r4  rO  rF  ra  rh  rn  r\  rt  rr  rp  r}  r~  r  r1  r  rC  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   rS   O   s  
&         . 
!       
 6       
4#(
0   
*              
<          
[       ]           
 A        
 	 

         * )          
@  
;
   
  
C  
A
0
,(


  
 
 
" 
  
!          
Q           
H           
1      rS   )xr  
__future__r   r   r  r|   platformr  datetimer   ior   r   	threadingr   typingr   r	   urllib.parser
   Z	xml.etreer   r   r   ru   r   Zurllib3._collectionsr   r   r   r   r   Zcommonconfigr   r   r   r   r   rc   r   Zcredentials.providersr   Z	datatypesr   r   r   r   r   r   r   r    r!   r"   Zdeleteobjectsr#   r$   r%   r  r&   r'   r(   Zhelpersr)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   Z	legalholdr=   Zlifecycleconfigr>   Znotificationconfigr?   Zobjectlockconfigr@   ZreplicationconfigrA   r,  rB   r   rC   rD   ZsignerrE   rF   r'  rG   rH   Z	sseconfigrI   r  rJ   ZversioningconfigrK   xmlrL   rM   rN   rO   rP   rQ   systemmachinerx   rS   r   r   r   r   <module>   sP   0X "