a
    !fp                    @   s  d 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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 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 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 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% 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* 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/ dd"l0m1Z1 dd#l0m2Z2 dd$l3m4Z4 dd%l3m5Z5 dd&l3m6Z6 dd'l3m7Z7 d(Z8d)Z9d*Z:d+Z;d,Z<d-Z=d.d/ Z>d0d1 Z?d2d3 Z@G d4d5 d5eAZBG d6d7 d7eAZCG d8d9 d9eAZDG d:d; d;eAZEeF ZGG d<d= d=eAZHG d>d? d?eZId@dA ZJdS )Bz4Create / interact with Google Cloud Storage buckets.    N)urlsplit)datetime_helpers)_datetime_to_rfc3339)_NOW)_rfc3339_nanos_to_datetime)NotFound)Policy)_signing)_add_etag_match_headers) _add_generation_match_parameters)_PropertyMixin)_scalar_property)_validate_name)generate_signed_url_v2)generate_signed_url_v4)_bucket_bound_hostname_url)	BucketACL)DefaultObjectACLBlob)_DEFAULT_TIMEOUT)ARCHIVE_STORAGE_CLASS)COLDLINE_STORAGE_CLASS)DUAL_REGION_LOCATION_TYPE)1DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS)#MULTI_REGIONAL_LEGACY_STORAGE_CLASS)MULTI_REGION_LOCATION_TYPE)NEARLINE_STORAGE_CLASS)"PUBLIC_ACCESS_PREVENTION_INHERITED)REGIONAL_LEGACY_STORAGE_CLASS)REGION_LOCATION_TYPE)STANDARD_STORAGE_CLASSBucketNotification)NONE_PAYLOAD_FORMAT)DEFAULT_RETRY)%DEFAULT_RETRY_IF_GENERATION_SPECIFIED)DEFAULT_RETRY_IF_ETAG_IN_JSON))DEFAULT_RETRY_IF_METAGENERATION_SPECIFIEDzlPass only one of 'uniform_bucket_level_access_enabled' / 'bucket_policy_only_enabled' to 'IAMConfiguration'.z'IAMConfiguration.bucket_policy_only_enabled' is deprecated.  Instead, use 'IAMConfiguration.uniform_bucket_level_access_enabled'.zpPass only one of 'uniform_bucket_level_access_lock_time' / 'bucket_policy_only_lock_time' to 'IAMConfiguration'.z'IAMConfiguration.bucket_policy_only_lock_time' is deprecated.  Instead, use 'IAMConfiguration.uniform_bucket_level_access_lock_time'.zAssignment to 'Bucket.location' is deprecated, as it is only valid before the bucket is created. Instead, pass the location to `Bucket.create`.zhttps://storage.googleapis.comc                 C   s$   t |dd|_| j|j dS )a  Grab prefixes after a :class:`~google.cloud.iterator.Page` started.

    :type iterator: :class:`~google.api_core.page_iterator.Iterator`
    :param iterator: The iterator that is currently in use.

    :type page: :class:`~google.cloud.api.core.page_iterator.Page`
    :param page: The page that was just created.

    :type response: dict
    :param response: The JSON API response for a page of blobs.
    prefixes N)tuplegetr)   update)iteratorpageresponser*   r*   \/var/www/html/python-backend/venv/lib/python3.9/site-packages/google/cloud/storage/bucket.py_blobs_page_startX   s    r2   c                 C   s&   | d}t|| jd}|| |S )a  Convert a JSON blob to the native object.

    .. note::

        This assumes that the ``bucket`` attribute has been
        added to the iterator after being created.

    :type iterator: :class:`~google.api_core.page_iterator.Iterator`
    :param iterator: The iterator that has retrieved the item.

    :type item: dict
    :param item: An item to be converted to a blob.

    :rtype: :class:`.Blob`
    :returns: The next blob in the page.
    namebucket)r,   r   r5   _set_properties)r.   itemr3   blobr*   r*   r1   _item_to_blobh   s    

r9   c                 C   s   t j|| jdS )a  Convert a JSON blob to the native object.

    .. note::

        This assumes that the ``bucket`` attribute has been
        added to the iterator after being created.

    :type iterator: :class:`~google.api_core.page_iterator.Iterator`
    :param iterator: The iterator that has retrieved the item.

    :type item: dict
    :param item: An item to be converted to a blob.

    :rtype: :class:`.BucketNotification`
    :returns: The next notification being iterated.
    r4   )r#   from_api_reprr5   )r.   r7   r*   r*   r1   _item_to_notification   s    r;   c                       s   e Zd ZdZd fdd	Zedd Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Z  ZS )LifecycleRuleConditionsaE  Map a single lifecycle rule for a bucket.

    See: https://cloud.google.com/storage/docs/lifecycle

    :type age: int
    :param age: (Optional) Apply rule action to items whose age, in days,
                exceeds this value.

    :type created_before: datetime.date
    :param created_before: (Optional) Apply rule action to items created
                           before this date.

    :type is_live: bool
    :param is_live: (Optional) If true, apply rule action to non-versioned
                    items, or to items with no newer versions. If false, apply
                    rule action to versioned items with at least one newer
                    version.

    :type matches_prefix: list(str)
    :param matches_prefix: (Optional) Apply rule action to items which
                                  any prefix matches the beginning of the item name.

    :type matches_storage_class: list(str), one or more of
                                 :attr:`Bucket.STORAGE_CLASSES`.
    :param matches_storage_class: (Optional) Apply rule action to items
                                  whose storage class matches this value.

    :type matches_suffix: list(str)
    :param matches_suffix: (Optional) Apply rule action to items which
                                  any suffix matches the end of the item name.

    :type number_of_newer_versions: int
    :param number_of_newer_versions: (Optional) Apply rule action to versioned
                                     items having N newer versions.

    :type days_since_custom_time: int
    :param days_since_custom_time: (Optional) Apply rule action to items whose number of days
                                   elapsed since the custom timestamp. This condition is relevant
                                   only for versioned objects. The value of the field must be a non
                                   negative integer. If it's zero, the object version will become
                                   eligible for lifecycle action as soon as it becomes custom.

    :type custom_time_before: :class:`datetime.date`
    :param custom_time_before: (Optional)  Date object parsed from RFC3339 valid date, apply rule action
                               to items whose custom time is before this date. This condition is relevant
                               only for versioned objects, e.g., 2019-03-16.

    :type days_since_noncurrent_time: int
    :param days_since_noncurrent_time: (Optional) Apply rule action to items whose number of days
                                        elapsed since the non current timestamp. This condition
                                        is relevant only for versioned objects. The value of the field
                                        must be a non negative integer. If it's zero, the object version
                                        will become eligible for lifecycle action as soon as it becomes
                                        non current.

    :type noncurrent_time_before: :class:`datetime.date`
    :param noncurrent_time_before: (Optional) Date object parsed from RFC3339 valid date, apply
                                   rule action to items whose non current time is before this date.
                                   This condition is relevant only for versioned objects, e.g, 2019-03-16.

    :raises ValueError: if no arguments are passed.
    NFc                    s   i }|d ur||d< |d ur(|  |d< |d ur8||d< |d urH||d< |d urX||d< |d urh||d< |d ur||  |d< |d ur||d< |	d ur|	  |d	< |
d ur|
|d
< |d ur||d< |s|stdtt| | d S )NagecreatedBeforeisLivematchesStorageClassnumNewerVersionsdaysSinceCustomTimecustomTimeBeforedaysSinceNoncurrentTimenoncurrentTimeBeforematchesPrefixmatchesSuffixzSupply at least one condition)	isoformat
ValueErrorsuperr<   __init__)selfr=   created_beforeis_livematches_storage_classnumber_of_newer_versionsdays_since_custom_timecustom_time_beforedays_since_noncurrent_timenoncurrent_time_beforematches_prefixmatches_suffix_factory
conditions	__class__r*   r1   rK      s4    z LifecycleRuleConditions.__init__c                 C   s   | dd}| | |S )zFactory:  construct instance from resource.

        :type resource: dict
        :param resource: mapping as returned from API call.

        :rtype: :class:`LifecycleRuleConditions`
        :returns: Instance created from resource.
        TrW   r-   clsresourceinstancer*   r*   r1   r:   
  s    


z%LifecycleRuleConditions.from_api_reprc                 C   s
   |  dS )zConditon's age value.r=   r,   rL   r*   r*   r1   r=     s    zLifecycleRuleConditions.agec                 C   s    |  d}|durt|S dS )z Conditon's created_before value.r>   Nr,   r   Zfrom_iso8601_daterL   beforer*   r*   r1   rM     s    
z&LifecycleRuleConditions.created_beforec                 C   s
   |  dS )zConditon's 'is_live' value.r?   ra   rb   r*   r*   r1   rN   $  s    zLifecycleRuleConditions.is_livec                 C   s
   |  dS )z"Conditon's 'matches_prefix' value.rF   ra   rb   r*   r*   r1   rU   )  s    z&LifecycleRuleConditions.matches_prefixc                 C   s
   |  dS )z)Conditon's 'matches_storage_class' value.r@   ra   rb   r*   r*   r1   rO   .  s    z-LifecycleRuleConditions.matches_storage_classc                 C   s
   |  dS )z"Conditon's 'matches_suffix' value.rG   ra   rb   r*   r*   r1   rV   3  s    z&LifecycleRuleConditions.matches_suffixc                 C   s
   |  dS )z,Conditon's 'number_of_newer_versions' value.rA   ra   rb   r*   r*   r1   rP   8  s    z0LifecycleRuleConditions.number_of_newer_versionsc                 C   s
   |  dS )z*Conditon's 'days_since_custom_time' value.rB   ra   rb   r*   r*   r1   rQ   =  s    z.LifecycleRuleConditions.days_since_custom_timec                 C   s    |  d}|durt|S dS )z&Conditon's 'custom_time_before' value.rC   Nrc   rd   r*   r*   r1   rR   B  s    
z*LifecycleRuleConditions.custom_time_beforec                 C   s
   |  dS )z.Conditon's 'days_since_noncurrent_time' value.rD   ra   rb   r*   r*   r1   rS   I  s    z2LifecycleRuleConditions.days_since_noncurrent_timec                 C   s    |  d}|durt|S dS )z*Conditon's 'noncurrent_time_before' value.rE   Nrc   rd   r*   r*   r1   rT   N  s    
z.LifecycleRuleConditions.noncurrent_time_before)NNNNNNNNNNNF)__name__
__module____qualname____doc__rK   classmethodr:   propertyr=   rM   rN   rU   rO   rV   rP   rQ   rR   rS   rT   __classcell__r*   r*   rY   r1   r<      sL   A            7










r<   c                       s,   e Zd ZdZ fddZedd Z  ZS )LifecycleRuleDeletezMap a lifecycle rule deleting matching items.

    :type kw: dict
    :params kw: arguments passed to :class:`LifecycleRuleConditions`.
    c                    s0   t f i |}ddit|d}t | d S )NtypeDeleteaction	conditionr<   dictrJ   rK   rL   kwrX   rulerY   r*   r1   rK   ]  s    zLifecycleRuleDelete.__init__c                 C   s   | dd}| | |S )zFactory:  construct instance from resource.

        :type resource: dict
        :param resource: mapping as returned from API call.

        :rtype: :class:`LifecycleRuleDelete`
        :returns: Instance created from resource.
        Tr[   r\   r]   r*   r*   r1   r:   b  s    


z!LifecycleRuleDelete.from_api_reprrf   rg   rh   ri   rK   rj   r:   rl   r*   r*   rY   r1   rm   V  s   rm   c                       s,   e Zd ZdZ fddZedd Z  ZS )LifecycleRuleSetStorageClassa,  Map a lifecycle rule updating storage class of matching items.

    :type storage_class: str, one of :attr:`Bucket.STORAGE_CLASSES`.
    :param storage_class: new storage class to assign to matching items.

    :type kw: dict
    :params kw: arguments passed to :class:`LifecycleRuleConditions`.
    c                    s2   t f i |}d|dt|d}t | d S )NSetStorageClass)rn   storageClassrp   rs   )rL   storage_classrv   rX   rw   rY   r*   r1   rK   {  s
    z%LifecycleRuleSetStorageClass.__init__c                 C   s&   |d }| |d dd}| | |S )zFactory:  construct instance from resource.

        :type resource: dict
        :param resource: mapping as returned from API call.

        :rtype: :class:`LifecycleRuleSetStorageClass`
        :returns: Instance created from resource.
        rq   r{   Tr[   r\   )r^   r_   rq   r`   r*   r*   r1   r:     s    

z*LifecycleRuleSetStorageClass.from_api_reprrx   r*   r*   rY   r1   ry   q  s   	ry   c                       s,   e Zd ZdZ fddZedd Z  ZS )+LifecycleRuleAbortIncompleteMultipartUploadzMap a rule aborting incomplete multipart uploads of matching items.

    The "age" lifecycle condition is the only supported condition for this rule.

    :type kw: dict
    :params kw: arguments passed to :class:`LifecycleRuleConditions`.
    c                    s0   t f i |}ddit|d}t | d S )Nrn   AbortIncompleteMultipartUploadrp   rs   ru   rY   r*   r1   rK     s
    z4LifecycleRuleAbortIncompleteMultipartUpload.__init__c                 C   s   | dd}| | |S )a  Factory:  construct instance from resource.

        :type resource: dict
        :param resource: mapping as returned from API call.

        :rtype: :class:`LifecycleRuleAbortIncompleteMultipartUpload`
        :returns: Instance created from resource.
        Tr[   r\   r]   r*   r*   r1   r:     s    


z9LifecycleRuleAbortIncompleteMultipartUpload.from_api_reprrx   r*   r*   rY   r1   r}     s   r}   c                       s   e Zd ZdZeeeeef fdd	Zedd Zedd Z	edd	 Z
e
jd
d	 Z
edd Zejdd Zedd Zedd Zejdd Zedd Z  ZS )IAMConfigurationa  Map a bucket's IAM configuration.

    :type bucket: :class:`Bucket`
    :params bucket: Bucket for which this instance is the policy.

    :type public_access_prevention: str
    :params public_access_prevention:
        (Optional) Whether the public access prevention policy is 'inherited' (default) or 'enforced'
        See: https://cloud.google.com/storage/docs/public-access-prevention

    :type uniform_bucket_level_access_enabled: bool
    :params bucket_policy_only_enabled:
        (Optional) Whether the IAM-only policy is enabled for the bucket.

    :type uniform_bucket_level_access_locked_time: :class:`datetime.datetime`
    :params uniform_bucket_level_locked_time:
        (Optional) When the bucket's IAM-only policy was enabled.
        This value should normally only be set by the back-end API.

    :type bucket_policy_only_enabled: bool
    :params bucket_policy_only_enabled:
        Deprecated alias for :data:`uniform_bucket_level_access_enabled`.

    :type bucket_policy_only_locked_time: :class:`datetime.datetime`
    :params bucket_policy_only_locked_time:
        Deprecated alias for :data:`uniform_bucket_level_access_locked_time`.
    c                    s   |t ur,|t urtttjttdd |}|t urX|t urDtttjttdd |}|t u rdd}|t u rpt	}d|i|d}|t urt
||d d< tt| | || _d S )N   
stacklevelFenabled)uniformBucketLevelAccesspublicAccessPreventionr   
lockedTime)_defaultrI   _UBLA_BPO_ENABLED_MESSAGEwarningswarn_BPO_ENABLED_MESSAGEDeprecationWarning_UBLA_BPO_LOCK_TIME_MESSAGE_BPO_LOCK_TIME_MESSAGEr   r   rJ   r   rK   _bucket)rL   r5   public_access_prevention#uniform_bucket_level_access_enabled'uniform_bucket_level_access_locked_timebucket_policy_only_enabledbucket_policy_only_locked_timedatarY   r*   r1   rK     s0    	zIAMConfiguration.__init__c                 C   s   | |}| | |S )aX  Factory:  construct instance from resource.

        :type bucket: :class:`Bucket`
        :params bucket: Bucket for which this instance is the policy.

        :type resource: dict
        :param resource: mapping as returned from API call.

        :rtype: :class:`IAMConfiguration`
        :returns: Instance created from resource.
        r\   )r^   r_   r5   r`   r*   r*   r1   r:     s    
zIAMConfiguration.from_api_reprc                 C   s   | j S )zBucket for which this instance is the policy.

        :rtype: :class:`Bucket`
        :returns: the instance's bucket.
        )r   rb   r*   r*   r1   r5     s    zIAMConfiguration.bucketc                 C   s   | d S )a(  Setting for public access prevention policy. Options are 'inherited' (default) or 'enforced'.

            See: https://cloud.google.com/storage/docs/public-access-prevention

        :rtype: string
        :returns: the public access prevention status, either 'enforced' or 'inherited'.
        r   r*   rb   r*   r*   r1   r     s    	z)IAMConfiguration.public_access_preventionc                 C   s   || d< | j d|  d S )Nr   iamConfiguration)r5   _patch_propertyrL   valuer*   r*   r1   r   $  s    c                 C   s   |  di }| ddS )zIf set, access checks only use bucket-level IAM policies or above.

        :rtype: bool
        :returns: whether the bucket is configured to allow only IAM.
        r   r   Fra   )rL   ublar*   r*   r1   r   )  s    z4IAMConfiguration.uniform_bucket_level_access_enabledc                 C   s*   |  di }t||d< | jd|  d S )Nr   r   r   )
setdefaultboolr5   r   )rL   r   r   r*   r*   r1   r   3  s    c                 C   s*   |  di }| d}|dur&t|}|S )a,  Deadline for changing :attr:`uniform_bucket_level_access_enabled` from true to false.

        If the bucket's :attr:`uniform_bucket_level_access_enabled` is true, this property
        is time time after which that setting becomes immutable.

        If the bucket's :attr:`uniform_bucket_level_access_enabled` is false, this property
        is ``None``.

        :rtype: Union[:class:`datetime.datetime`, None]
        :returns:  (readonly) Time after which :attr:`uniform_bucket_level_access_enabled` will
                   be frozen as true.
        r   r   N)r,   r   )rL   r   Zstampr*   r*   r1   r   9  s
    
z8IAMConfiguration.uniform_bucket_level_access_locked_timec                 C   s   | j S )zDeprecated alias for :attr:`uniform_bucket_level_access_enabled`.

        :rtype: bool
        :returns: whether the bucket is configured to allow only IAM.
        )r   rb   r*   r*   r1   r   M  s    z+IAMConfiguration.bucket_policy_only_enabledc                 C   s   t jttdd || _d S )Nr   r   )r   r   r   r   r   r   r*   r*   r1   r   V  s    c                 C   s   | j S )a  Deprecated alias for :attr:`uniform_bucket_level_access_locked_time`.

        :rtype: Union[:class:`datetime.datetime`, None]
        :returns:
            (readonly) Time after which :attr:`bucket_policy_only_enabled` will
            be frozen as true.
        )r   rb   r*   r*   r1   r   [  s    	z/IAMConfiguration.bucket_policy_only_locked_time)rf   rg   rh   ri   r   rK   rj   r:   rk   r5   r   setterr   r   r   r   rl   r*   r*   rY   r1   r     s6   ,





	



r   c                       s  e Zd ZdZdZeeeee	e
efZeeefZd fdd	Zdd Zedd	 Z fd
dZedd Zejdd Zedd ZedddZdddZdddddedfddZdeddddefddZ dddddeefddZ!dedde"f fdd	Z#ddeddddef fdd	Z$dedde"f fd d!	Z%ed"d# Z&ed$d% Z'e(d&d' Z)ed(d) Z*dddddddddeefd*d+Z+dddddddddddeefd,d-Z,deefd.d/Z-deefd0d1Z.d2dddeefd3d4Z/ddddddee0fd5d6Z1ddd2edddde0f	d7d8Z2ddd9dddddddddee0fd:d;Z3dddddddddee0fd<d=Z4ed>d? Z5e5jd@d? Z5e6dAZ7edBdC Z8e8jdDdC Z8edEdF Z9e9jdGdF Z9edHdI Z:edJdK Z;edLdM Z<edNdO Z=e=jdPdO Z=dQdR Z>dSdT Z?dUdV Z@dWdX ZAe6dYZBedZd[ ZCeCjd\d[ ZCed]d^ ZDed_d` ZEdadb ZFddddeZGdfdg ZHedhdi ZIedjdk ZJedldm ZKedndo ZLedpdq ZMedrds ZNeNjdtds ZNedudv ZOedwdx ZPePjdydx ZPedzd{ ZQed|d} ZReRjd~d} ZRedd ZSeSjdd ZSedd ZTeTjdd ZTedd ZUdddZVdd ZWddeefddZXdeeYfddZZdeefddZ[d2d2dedde"fddZ\d2d2dedde"fddZ]dddZ^deefddZ_de`ddddddd2ddfddZa  ZbS )Bucketa&  A class representing a Bucket on Cloud Storage.

    :type client: :class:`google.cloud.storage.client.Client`
    :param client: A client which holds credentials and project configuration
                   for the bucket (which requires a project).

    :type name: str
    :param name: The name of the bucket. Bucket names must start and end with a
                 number or letter.

    :type user_project: str
    :param user_project: (Optional) the project ID to be billed for API
                         requests made via this instance.
       Nc                    sF   t |}tt| j|d || _t| | _t| | _t	 | _
|| _dS )zJ
        property :attr:`name`
            Get the bucket's name.
        r3   N)r   rJ   r   rK   _clientr   _aclr   _default_object_aclset_label_removals_user_project)rL   clientr3   user_projectrY   r*   r1   rK     s    

zBucket.__init__c                 C   s   d| j  dS )Nz	<Bucket: >r   rb   r*   r*   r1   __repr__  s    zBucket.__repr__c                 C   s   | j S )z The client bound to this bucket.)r   rb   r*   r*   r1   r     s    zBucket.clientc                    s   | j   tt| |S )zSet the properties for the current object.

        :type value: dict or :class:`google.cloud.storage.batch._FutureDict`
        :param value: The properties to be set.
        )r   clearrJ   r   r6   r   rY   r*   r1   r6     s    
zBucket._set_propertiesc                 C   s   | j dS )zGet the RPO (Recovery Point Objective) of this bucket

        See: https://cloud.google.com/storage/docs/managing-turbo-replication

        "ASYNC_TURBO" or "DEFAULT"
        :rtype: str
        rpo_propertiesr,   rb   r*   r*   r1   r     s    	z
Bucket.rpoc                 C   s   |  d| dS )z
        Set the RPO (Recovery Point Objective) of this bucket.

        See: https://cloud.google.com/storage/docs/managing-turbo-replication

        :type value: str
        :param value: "ASYNC_TURBO" or "DEFAULT"
        r   Nr   r   r*   r*   r1   r     s    
c                 C   s   | j S )aJ  Project ID to be billed for API requests made via this bucket.

        If unset, API requests are billed to the bucket owner.

        A user project is required for all operations on Requester Pays buckets.

        See https://cloud.google.com/storage/docs/requester-pays#requirements for details.

        :rtype: str
        )r   rb   r*   r*   r1   r     s    zBucket.user_projectc                 C   s.   t |\}}}}}|dkr"td| ||dS )a  Get a constructor for bucket object by URI.

        .. code-block:: python

            from google.cloud import storage
            from google.cloud.storage.bucket import Bucket
            client = storage.Client()
            bucket = Bucket.from_string("gs://bucket", client=client)

        :type uri: str
        :param uri: The bucket uri pass to get bucket object.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  Application code should
            *always* pass ``client``.

        :rtype: :class:`google.cloud.storage.bucket.Bucket`
        :returns: The bucket object created.
        gszURI scheme must be gsr   )r   rI   )r^   urir   schemenetlocpathqueryfragr*   r*   r1   from_string  s    zBucket.from_stringc                 C   s   t || ||||dS )a  Factory constructor for blob object.

        .. note::
          This will not make an HTTP request; it simply instantiates
          a blob object owned by this bucket.

        :type blob_name: str
        :param blob_name: The name of the blob to be instantiated.

        :type chunk_size: int
        :param chunk_size: The size of a chunk of data whenever iterating
                           (in bytes). This must be a multiple of 256 KB per
                           the API specification.

        :type encryption_key: bytes
        :param encryption_key:
            (Optional) 32 byte encryption key for customer-supplied encryption.

        :type kms_key_name: str
        :param kms_key_name:
            (Optional) Resource name of KMS key used to encrypt blob's content.

        :type generation: long
        :param generation: (Optional) If present, selects a specific revision of
                           this object.

        :rtype: :class:`google.cloud.storage.blob.Blob`
        :returns: The blob object created.
        )r3   r5   
chunk_sizeencryption_keykms_key_name
generationr   )rL   	blob_namer   r   r   r   r*   r*   r1   r8     s    %zBucket.blobc              
   C   s   t | |||||||dS )zFactory:  create a notification resource for the bucket.

        See: :class:`.BucketNotification` for parameters.

        :rtype: :class:`.BucketNotification`
        )
topic_nametopic_projectcustom_attributesevent_typesblob_name_prefixpayload_formatnotification_idr"   )rL   r   r   r   r   r   r   r   r*   r*   r1   notification$  s    zBucket.notificationc           
      C   s|   |  |}ddi}| jdur&| j|d< t|||d i }	t|	||d z|j| j||	||dd W n tyv   Y dS 0 d	S )
a  Determines whether or not this bucket exists.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use. If not passed, falls back
                       to the ``client`` stored on the current bucket.

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

        :type if_etag_match: Union[str, Set[str]]
        :param if_etag_match: (Optional) Make the operation conditional on whether the
                              bucket's current ETag matches the given value.

        :type if_etag_not_match: Union[str, Set[str]])
        :param if_etag_not_match: (Optional) Make the operation conditional on whether the
                                  bucket's current ETag does not match the given value.

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        bucket's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            bucket's current metageneration does not match the given value.

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: bool
        :returns: True if the bucket exists in Cloud Storage.
        fieldsr3   NuserProjectif_metageneration_matchif_metageneration_not_match)if_etag_matchif_etag_not_match)query_paramsheaderstimeoutretry_target_objectFT)_require_clientr   r   r
   _get_resourcer   r   )
rL   r   r   r   r   r   r   r   r   r   r*   r*   r1   exists?  s2    /



zBucket.existsc              
   C   s*   |  |}|j| || j|||||d dS )a  Creates current bucket.

        If the bucket already exists, will raise
        :class:`google.cloud.exceptions.Conflict`.

        This implements "storage.buckets.insert".

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use. If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type project: str
        :param project: (Optional) The project under which the bucket is to
                        be created. If not passed, uses the project set on
                        the client.
        :raises ValueError: if ``project`` is None and client's
                            :attr:`project` is also None.

        :type location: str
        :param location: (Optional) The location of the bucket. If not passed,
                         the default location, US, will be used. See
                         https://cloud.google.com/storage/docs/bucket-locations

        :type predefined_acl: str
        :param predefined_acl:
            (Optional) Name of predefined ACL to apply to bucket. See:
            https://cloud.google.com/storage/docs/access-control/lists#predefined-acl

        :type predefined_default_object_acl: str
        :param predefined_default_object_acl:
            (Optional) Name of predefined ACL to apply to bucket's objects. See:
            https://cloud.google.com/storage/docs/access-control/lists#predefined-acl

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        )Zbucket_or_nameprojectr   locationpredefined_aclpredefined_default_object_aclr   r   N)r   Zcreate_bucketr   )rL   r   r   r   r   r   r   r   r*   r*   r1   create  s    8
zBucket.createc                    s   t t| j|||||d dS )a9  Sends all properties in a PUT request.

        Updates the ``_properties`` with the response from the backend.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

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

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        blob's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            blob's current metageneration does not match the given value.

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        r   r   r   r   r   N)rJ   r   r-   )rL   r   r   r   r   r   rY   r*   r1   r-     s    $
zBucket.updateZnoAclc	           	   
      s$   t t| j||||||||d dS )a  Reload properties from Cloud Storage.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

        :type projection: str
        :param projection: (Optional) If used, must be 'full' or 'noAcl'.
                           Defaults to ``'noAcl'``. Specifies the set of
                           properties to return.

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

        :type if_etag_match: Union[str, Set[str]]
        :param if_etag_match: (Optional) Make the operation conditional on whether the
                              bucket's current ETag matches the given value.

        :type if_etag_not_match: Union[str, Set[str]])
        :param if_etag_not_match: (Optional) Make the operation conditional on whether the
                                  bucket's current ETag does not match the given value.

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        bucket's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            bucket's current metageneration does not match the given value.

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        )r   
projectionr   r   r   r   r   r   N)rJ   r   reload)	rL   r   r   r   r   r   r   r   r   rY   r*   r1   r     s    2
zBucket.reloadc                    sX   | j r:| jd | jdi  | j D ]}d| jd |< q&tt| j|||||d dS )aC  Sends all changed properties in a PATCH request.

        Updates the ``_properties`` with the response from the backend.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

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

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        blob's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            blob's current metageneration does not match the given value.

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        labelsN)r   r   r   r   r   )r   Z_changesaddr   r   rJ   r   patch)rL   r   r   r   r   r   Zremoved_labelrY   r*   r1   r   @  s    &

zBucket.patchc                 C   s   | j S )zCreate our ACL on demand.)r   rb   r*   r*   r1   aclu  s    z
Bucket.aclc                 C   s   | j S )z&Create our defaultObjectACL on demand.)r   rb   r*   r*   r1   default_object_aclz  s    zBucket.default_object_aclc                 C   s   d|  S )zRelative URL path for a bucket.

        :type bucket_name: str
        :param bucket_name: The bucket name in the path.

        :rtype: str
        :returns: The relative URL path for ``bucket_name``.
        /b/r*   )bucket_namer*   r*   r1   path_helper  s    
zBucket.path_helperc                 C   s   | j std| | j S )zThe URL path to this bucket.z*Cannot determine path without bucket name.)r3   rI   r   rb   r*   r*   r1   r     s    zBucket.pathc                 K   sV   t f | |||d|}z |j|||||||	|
|d	 W n tyL   Y dS 0 |S dS )a	  Get a blob object by name.

        See a [code sample](https://cloud.google.com/storage/docs/samples/storage-get-metadata#storage_get_metadata-python)
        on how to retrieve metadata of an object.

        If :attr:`user_project` is set, bills the API request to that project.

        :type blob_name: str
        :param blob_name: The name of the blob to retrieve.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type encryption_key: bytes
        :param encryption_key:
            (Optional) 32 byte encryption key for customer-supplied encryption.
            See
            https://cloud.google.com/storage/docs/encryption#customer-supplied.

        :type generation: long
        :param generation:
            (Optional) If present, selects a specific revision of this object.

        :type if_etag_match: Union[str, Set[str]]
        :param if_etag_match:
            (Optional) See :ref:`using-if-etag-match`

        :type if_etag_not_match: Union[str, Set[str]]
        :param if_etag_not_match:
            (Optional) See :ref:`using-if-etag-not-match`

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :param kwargs: Keyword arguments to pass to the
                       :class:`~google.cloud.storage.blob.Blob` constructor.

        :rtype: :class:`google.cloud.storage.blob.Blob` or None
        :returns: The blob object if it exists, otherwise None.
        )r5   r3   r   r   )	r   r   r   r   if_generation_matchif_generation_not_matchr   r   r   N)r   r   r   )rL   r   r   r   r   r   r   r   r   r   r   r   r   kwargsr8   r*   r*   r1   get_blob  s.    P
zBucket.get_blobc                 C   s.   |  |}|j| |||||||||	|
||dS )a  Return an iterator used to find blobs in the bucket.

        If :attr:`user_project` is set, bills the API request to that project.

        :type max_results: int
        :param max_results:
            (Optional) The maximum number of blobs to return.

        :type page_token: str
        :param page_token:
            (Optional) If present, return the next batch of blobs, using the
            value, which must correspond to the ``nextPageToken`` value
            returned in the previous response.  Deprecated: use the ``pages``
            property of the returned iterator instead of manually passing the
            token.

        :type prefix: str
        :param prefix: (Optional) Prefix used to filter blobs.

        :type delimiter: str
        :param delimiter: (Optional) Delimiter, used with ``prefix`` to
                          emulate hierarchy.

        :type start_offset: str
        :param start_offset:
            (Optional) Filter results to objects whose names are
            lexicographically equal to or after ``startOffset``. If
            ``endOffset`` is also set, the objects listed will have names
            between ``startOffset`` (inclusive) and ``endOffset`` (exclusive).

        :type end_offset: str
        :param end_offset:
            (Optional) Filter results to objects whose names are
            lexicographically before ``endOffset``. If ``startOffset`` is also
            set, the objects listed will have names between ``startOffset``
            (inclusive) and ``endOffset`` (exclusive).

        :type include_trailing_delimiter: boolean
        :param include_trailing_delimiter:
            (Optional) If true, objects that end in exactly one instance of
            ``delimiter`` will have their metadata included in ``items`` in
            addition to ``prefixes``.

        :type versions: bool
        :param versions: (Optional) Whether object versions should be returned
                         as separate blobs.

        :type projection: str
        :param projection: (Optional) If used, must be 'full' or 'noAcl'.
                           Defaults to ``'noAcl'``. Specifies the set of
                           properties to return.

        :type fields: str
        :param fields:
            (Optional) Selector specifying which fields to include
            in a partial response. Must be a list of fields. For
            example to get a partial response with just the next
            page token and the name and language of each blob returned:
            ``'items(name,contentLanguage),nextPageToken'``.
            See: https://cloud.google.com/storage/docs/json_api/v1/parameters#fields

        :type client: :class:`~google.cloud.storage.client.Client`
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`~google.api_core.page_iterator.Iterator`
        :returns: Iterator of all :class:`~google.cloud.storage.blob.Blob`
                  in this bucket matching the arguments.
        )max_results
page_tokenprefix	delimiterstart_offset
end_offsetinclude_trailing_delimiterversionsr   r   r   r   )r   
list_blobs)rL   r   r   r   r   r   r   r   r   r   r   r   r   r   r*   r*   r1   r     s     ^
zBucket.list_blobsc                 C   s0   |  |}| jd }|j|t||d}| |_|S )a  List Pub / Sub notifications for this bucket.

        See:
        https://cloud.google.com/storage/docs/json_api/v1/notifications/list

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.
        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: list of :class:`.BucketNotification`
        :returns: notification instances
        z/notificationConfigs)r   r   )r   r   Z_list_resourcer;   r5   )rL   r   r   r   r   r.   r*   r*   r1   list_notificationsm  s    

zBucket.list_notificationsc                 C   s    | j |d}|j|||d |S )a  Get Pub / Sub notification for this bucket.

        See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/notifications/get)
        and a [code sample](https://cloud.google.com/storage/docs/samples/storage-print-pubsub-bucket-notification#storage_print_pubsub_bucket_notification-python).

        If :attr:`user_project` is set, bills the API request to that project.

        :type notification_id: str
        :param notification_id: The notification id to retrieve the notification configuration.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.
        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`.BucketNotification`
        :returns: notification instance.
        )r   )r   r   r   )r   r   )rL   r   r   r   r   r   r*   r*   r1   get_notification  s    !zBucket.get_notificationFc           
      C   s   |  |}i }| jdur"| j|d< t|||d |rt| j| jd |||d}t|| jkrrd| jf }	t|	| j|dd |||d	 |j	| j
|||dd
 dS )a  Delete this bucket.

        The bucket **must** be empty in order to submit a delete request. If
        ``force=True`` is passed, this will first attempt to delete all the
        objects / blobs in the bucket (i.e. try to empty the bucket).

        If the bucket doesn't exist, this will raise
        :class:`google.cloud.exceptions.NotFound`. If the bucket is not empty
        (and ``force=False``), will raise :class:`google.cloud.exceptions.Conflict`.

        If ``force=True`` and the bucket contains more than 256 objects / blobs
        this will cowardly refuse to delete the objects (or the bucket). This
        is to prevent accidental bucket deletion and to prevent extremely long
        runtime of this method.

        If :attr:`user_project` is set, bills the API request to that project.

        :type force: bool
        :param force: If True, empties the bucket's objects then deletes it.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use. If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        blob's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            blob's current metageneration does not match the given value.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises: :class:`ValueError` if ``force`` is ``True`` and the bucket
                 contains more than 256 objects / blobs.
        Nr   r      )r   r   r   r   zRefusing to delete bucket with more than %d objects. If you actually want to delete this bucket, please delete the objects yourself before calling Bucket.delete().c                 S   s   d S )Nr*   )r8   r*   r*   r1   <lambda>      zBucket.delete.<locals>.<lambda>)on_errorr   r   r   r   r   r   r   )r   r   r   listr   _MAX_OBJECTS_FOR_ITERATIONlenrI   delete_blobs_delete_resourcer   )
rL   forcer   r   r   r   r   r   blobsmessager*   r*   r1   delete  sJ    6


zBucket.deletec
                 C   sP   |  |}t|| |d}
t|
j}t|||||d |j|
j|||	dd dS )aO  Deletes a blob from the current bucket.

        If :attr:`user_project` is set, bills the API request to that project.

        :type blob_name: str
        :param blob_name: A blob name to delete.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use. If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type generation: long
        :param generation: (Optional) If present, permanently deletes a specific
                           revision of this object.

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises: :class:`google.cloud.exceptions.NotFound` Raises a NotFound
                 if the blob isn't found. To suppress
                 the exception, use :meth:`delete_blobs` by passing a no-op
                 ``on_error`` callback.
        )r5   r   r   r   r   r   Nr   )r   r   copydeepcopyZ_query_paramsr   r   r   )rL   r   r   r   r   r   r   r   r   r   r8   r   r*   r*   r1   delete_blob  s"    :

zBucket.delete_blobc                 C   s   t t|||||	d t|pg }t|p*g }t|p6g }t|	pBg }	|D ]}z^|}d}t|tsv|j}|rr|jnd}| j|||t|dt|dt|dt|	d||
d	 W qJ t	y   |dur|| n Y qJ0 qJdS )a  Deletes a list of blobs from the current bucket.

        Uses :meth:`delete_blob` to delete each individual blob.

        By default, any generation information in the list of blobs is ignored, and the
        live versions of all blobs are deleted. Set `preserve_generation` to True
        if blob generation should instead be propagated from the list of blobs.

        If :attr:`user_project` is set, bills the API request to that project.

        :type blobs: list
        :param blobs: A list of :class:`~google.cloud.storage.blob.Blob`-s or
                      blob names to delete.

        :type on_error: callable
        :param on_error: (Optional) Takes single argument: ``blob``.
                         Called once for each blob raising
                         :class:`~google.cloud.exceptions.NotFound`;
                         otherwise, the exception is propagated.

        :type client: :class:`~google.cloud.storage.client.Client`
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type preserve_generation: bool
        :param preserve_generation: (Optional) Deletes only the generation specified on the blob object,
                                    instead of the live version, if set to True. Only :class:~google.cloud.storage.blob.Blob
                                    objects can have their generation set in this way.
                                    Default: False.

        :type if_generation_match: list of long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`
            Note that the length of the list must match the length of
            The list must match ``blobs`` item-to-item.

        :type if_generation_not_match: list of long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`
            The list must match ``blobs`` item-to-item.

        :type if_metageneration_match: list of long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`
            The list must match ``blobs`` item-to-item.

        :type if_metageneration_not_match: list of long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`
            The list must match ``blobs`` item-to-item.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises: :class:`~google.cloud.exceptions.NotFound` (if
                 `on_error` is not passed).
        r  N)r   r   r   r   r   r   r   r   )
_raise_if_len_differsr   iter
isinstancestrr3   r   r  nextr   )rL   r   r   r   Zpreserve_generationr   r   r   r   r   r   r8   r   r   r*   r*   r1   r   n  sB    L


zBucket.delete_blobsTc                 C   s   |  |}i }| jdur"| j|d< |dur2||d< t||||	|
||||d	 |du rZ|j}t||d}|jd |j }|j|d||||d}|s|jji ||d |	| |S )	a+  Copy the given blob to the given bucket, optionally with a new name.

        If :attr:`user_project` is set, bills the API request to that project.

        See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/objects/copy)
        and a [code sample](https://cloud.google.com/storage/docs/samples/storage-copy-file#storage_copy_file-python).

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

        :type destination_bucket: :class:`google.cloud.storage.bucket.Bucket`
        :param destination_bucket: The bucket into which the blob should be
                                   copied.

        :type new_name: str
        :param new_name: (Optional) The new name for the copied file.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use. If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type preserve_acl: bool
        :param preserve_acl: DEPRECATED. This argument is not functional!
                             (Optional) Copies ACL from old blob to new blob.
                             Default: True.

        :type source_generation: long
        :param source_generation: (Optional) The generation of the blob to be
                                  copied.

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`
            Note that the generation to be matched is that of the
            ``destination`` blob.

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`
            Note that the generation to be matched is that of the
            ``destination`` blob.

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`
            Note that the metageneration to be matched is that of the
            ``destination`` blob.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`
            Note that the metageneration to be matched is that of the
            ``destination`` blob.

        :type if_source_generation_match: long
        :param if_source_generation_match:
            (Optional) Makes the operation conditional on whether the source
            object's generation matches the given value.

        :type if_source_generation_not_match: long
        :param if_source_generation_not_match:
            (Optional) Makes the operation conditional on whether the source
            object's generation does not match the given value.

        :type if_source_metageneration_match: long
        :param if_source_metageneration_match:
            (Optional) Makes the operation conditional on whether the source
            object's current metageneration matches the given value.

        :type if_source_metageneration_not_match: long
        :param if_source_metageneration_not_match:
            (Optional) Makes the operation conditional on whether the source
            object's current metageneration does not match the given value.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`google.cloud.storage.blob.Blob`
        :returns: The new Blob.
        Nr   ZsourceGeneration)r   r   r   r   if_source_generation_matchif_source_generation_not_matchif_source_metageneration_match"if_source_metageneration_not_match)r5   r3   z/copyTor   )r   r   r   )
r   r   r   r3   r   r   _post_resourcer   saver6   )rL   r8   Zdestination_bucketnew_namer   Zpreserve_aclZsource_generationr   r   r   r   r
  r  r  r  r   r   r   new_blobZapi_pathZcopy_resultr*   r*   r1   	copy_blob  sB    j


	
zBucket.copy_blobc                 C   sP   |j |k}| j|| |||||||||	|
||d}|sL|j||||	|
||d |S )a  Rename the given blob using copy and delete operations.

        If :attr:`user_project` is set, bills the API request to that project.

        Effectively, copies blob to the same bucket with a new name, then
        deletes the blob.

        .. warning::

          This method will first duplicate the data and then delete the
          old blob.  This means that with very large objects renaming
          could be a very (temporarily) costly or a very slow operation.
          If you need more control over the copy and deletion, instead
          use `google.cloud.storage.blob.Blob.copy_to` and
          `google.cloud.storage.blob.Blob.delete` directly.

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

        :type new_name: str
        :param new_name: The new name for this blob.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`
            Note that the generation to be matched is that of the
            ``destination`` blob.

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`
            Note that the generation to be matched is that of the
            ``destination`` blob.

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`
            Note that the metageneration to be matched is that of the
            ``destination`` blob.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`
            Note that the metageneration to be matched is that of the
            ``destination`` blob.

        :type if_source_generation_match: long
        :param if_source_generation_match:
            (Optional) Makes the operation conditional on whether the source
            object's generation matches the given value. Also used in the
            (implied) delete request.

        :type if_source_generation_not_match: long
        :param if_source_generation_not_match:
            (Optional) Makes the operation conditional on whether the source
            object's generation does not match the given value. Also used in
            the (implied) delete request.

        :type if_source_metageneration_match: long
        :param if_source_metageneration_match:
            (Optional) Makes the operation conditional on whether the source
            object's current metageneration matches the given value. Also used
            in the (implied) delete request.

        :type if_source_metageneration_not_match: long
        :param if_source_metageneration_not_match:
            (Optional) Makes the operation conditional on whether the source
            object's current metageneration does not match the given value.
            Also used in the (implied) delete request.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`Blob`
        :returns: The newly-renamed blob.
        )r   r   r   r   r   r   r
  r  r  r  r   )r   r   r   r   r   r   r   )r3   r  r   )rL   r8   r  r   r   r   r   r   r
  r  r  r  r   r   Z	same_namer  r*   r*   r1   rename_blobr  s8    g
	zBucket.rename_blobc                 C   s   dd | j ddD S )a  Retrieve or set CORS policies configured for this bucket.

        See http://www.w3.org/TR/cors/ and
             https://cloud.google.com/storage/docs/json_api/v1/buckets

        .. note::

           The getter for this property returns a list which contains
           *copies* of the bucket's CORS policy mappings.  Mutating the list
           or one of its dicts has no effect unless you then re-assign the
           dict via the setter.  E.g.:

           >>> policies = bucket.cors
           >>> policies.append({'origin': '/foo', ...})
           >>> policies[1]['maxAgeSeconds'] = 3600
           >>> del policies[0]
           >>> bucket.cors = policies
           >>> bucket.update()

        :setter: Set CORS policies for this bucket.
        :getter: Gets the CORS policies for this bucket.

        :rtype: list of dictionaries
        :returns: A sequence of mappings describing each CORS policy.
        c                 S   s   g | ]}t |qS r*   )r  r  ).0policyr*   r*   r1   
<listcomp>  r   zBucket.cors.<locals>.<listcomp>corsr*   r   rb   r*   r*   r1   r    s    zBucket.corsc                 C   s   |  d| dS )a"  Set CORS policies configured for this bucket.

        See http://www.w3.org/TR/cors/ and
             https://cloud.google.com/storage/docs/json_api/v1/buckets

        :type entries: list of dictionaries
        :param entries: A sequence of mappings describing each CORS policy.
        r  Nr   )rL   entriesr*   r*   r1   r    s    
ZdefaultEventBasedHoldc                 C   s   | j di }|dS )a  Retrieve / set default KMS encryption key for objects in the bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :setter: Set default KMS encryption key for items in this bucket.
        :getter: Get default KMS encryption key for items in this bucket.

        :rtype: str
        :returns: Default KMS encryption key, or ``None`` if not set.
        
encryptiondefaultKmsKeyNamer   )rL   encryption_configr*   r*   r1   default_kms_key_name0  s    zBucket.default_kms_key_namec                 C   s&   | j di }||d< | d| dS )zSet default KMS encryption key for objects in the bucket.

        :type value: str or None
        :param value: new KMS key name (None to clear any existing key).
        r  r  N)r   r,   r   )rL   r   r  r*   r*   r1   r  ?  s    c                 C   s"   | j d}|du ri S t|S )a  Retrieve or set labels assigned to this bucket.

        See
        https://cloud.google.com/storage/docs/json_api/v1/buckets#labels

        .. note::

           The getter for this property returns a dict which is a *copy*
           of the bucket's labels.  Mutating that dict has no effect unless
           you then re-assign the dict via the setter.  E.g.:

           >>> labels = bucket.labels
           >>> labels['new_key'] = 'some-label'
           >>> del labels['old_key']
           >>> bucket.labels = labels
           >>> bucket.update()

        :setter: Set labels for this bucket.
        :getter: Gets the labels for this bucket.

        :rtype: :class:`dict`
        :returns: Name-value pairs (string->string) labelling the bucket.
        r   Nr   r,   r  r  )rL   r   r*   r*   r1   r   J  s    zBucket.labelsc                 C   sj   t dd | j D }t dd | D }| j||| _dd | D }| dt	| dS )zSet labels assigned to this bucket.

        See
        https://cloud.google.com/storage/docs/json_api/v1/buckets#labels

        :type mapping: :class:`dict`
        :param mapping: Name-value pairs (string->string) labelling the bucket.
        c                 S   s   g | ]}|qS r*   r*   r  kr*   r*   r1   r  t  r   z!Bucket.labels.<locals>.<listcomp>c                 S   s   g | ]}|qS r*   r*   r  r*   r*   r1   r  u  r   c                 S   s   i | ]\}}|t |qS r*   )r  )r  r  vr*   r*   r1   
<dictcomp>w  r   z!Bucket.labels.<locals>.<dictcomp>r   N)
r   r   keysr   union
differenceitemsr   r  r  )rL   mappingexistingincomingr*   r*   r1   r   h  s
    c                 C   s   | j dS )aV  Retrieve the ETag for the bucket.

        See https://tools.ietf.org/html/rfc2616#section-3.11 and
             https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: str or ``NoneType``
        :returns: The bucket etag or ``None`` if the bucket's
                  resource has not been loaded from the server.
        etagr   rb   r*   r*   r1   r)  |  s    zBucket.etagc                 C   s   | j dS )a  Retrieve the ID for the bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: str or ``NoneType``
        :returns: The ID of the bucket or ``None`` if the bucket's
                  resource has not been loaded from the server.
        idr   rb   r*   r*   r1   r*    s    
z	Bucket.idc                 C   s   | j di }t|| S )zRetrieve IAM configuration for this bucket.

        :rtype: :class:`IAMConfiguration`
        :returns: an instance for managing the bucket's IAM configuration.
        r   )r   r,   r   r:   rL   infor*   r*   r1   iam_configuration  s    zBucket.iam_configurationc                 c   s   | j di }|ddD ]h}|d d }|dkr@t|V  q|dkrVt|V  q|dkrlt|V  qtjd	|t	d
d qdS )a  Retrieve or set lifecycle rules configured for this bucket.

        See https://cloud.google.com/storage/docs/lifecycle and
             https://cloud.google.com/storage/docs/json_api/v1/buckets

        .. note::

           The getter for this property returns a generator which yields
           *copies* of the bucket's lifecycle rules mappings.  Mutating the
           output dicts has no effect unless you then re-assign the dict via
           the setter.  E.g.:

           >>> rules = list(bucket.lifecycle_rules)
           >>> rules.append({'origin': '/foo', ...})
           >>> rules[1]['rule']['action']['type'] = 'Delete'
           >>> del rules[0]
           >>> bucket.lifecycle_rules = rules
           >>> bucket.update()

        :setter: Set lifecycle rules for this bucket.
        :getter: Gets the lifecycle rules for this bucket.

        :rtype: generator(dict)
        :returns: A sequence of mappings describing each lifecycle rule.
        	lifecyclerw   r*   rq   rn   ro   rz   r~   zgUnknown lifecycle rule type received: {}. Please upgrade to the latest version of google-cloud-storage.r   r   N)
r   r,   rm   r:   ry   r}   r   r   formatUserWarning)rL   r,  rw   Zaction_typer*   r*   r1   lifecycle_rules  s     zBucket.lifecycle_rulesc                 C   s"   dd |D }|  dd|i dS )a8  Set lifecycle rules configured for this bucket.

        See https://cloud.google.com/storage/docs/lifecycle and
             https://cloud.google.com/storage/docs/json_api/v1/buckets

        :type rules: list of dictionaries
        :param rules: A sequence of mappings describing each lifecycle rule.
        c                 S   s   g | ]}t |qS r*   )rt   )r  rw   r*   r*   r1   r    r   z*Bucket.lifecycle_rules.<locals>.<listcomp>r.  rw   Nr   )rL   rulesr*   r*   r1   r1    s    
c                 C   s
   g | _ dS )zClear lifecycle rules configured for this bucket.

        See https://cloud.google.com/storage/docs/lifecycle and
             https://cloud.google.com/storage/docs/json_api/v1/buckets
        N)r1  rb   r*   r*   r1   clear_lifecyle_rules  s    zBucket.clear_lifecyle_rulesc                 K   s(   t | j}|tf i | || _dS )a  Add a "delete" rule to lifecycle rules configured for this bucket.

        This defines a [lifecycle configuration](https://cloud.google.com/storage/docs/lifecycle),
        which is set on the bucket. For the general format of a lifecycle configuration, see the
        [bucket resource representation for JSON](https://cloud.google.com/storage/docs/json_api/v1/buckets).
        See also a [code sample](https://cloud.google.com/storage/docs/samples/storage-enable-bucket-lifecycle-management#storage_enable_bucket_lifecycle_management-python).

        :type kw: dict
        :params kw: arguments passed to :class:`LifecycleRuleConditions`.
        N)r   r1  appendrm   rL   rv   r2  r*   r*   r1   add_lifecycle_delete_rule  s    
z Bucket.add_lifecycle_delete_rulec                 K   s*   t | j}|t|fi | || _dS )a`  Add a "set storage class" rule to lifecycle rules.

        This defines a [lifecycle configuration](https://cloud.google.com/storage/docs/lifecycle),
        which is set on the bucket. For the general format of a lifecycle configuration, see the
        [bucket resource representation for JSON](https://cloud.google.com/storage/docs/json_api/v1/buckets).

        :type storage_class: str, one of :attr:`STORAGE_CLASSES`.
        :param storage_class: new storage class to assign to matching items.

        :type kw: dict
        :params kw: arguments passed to :class:`LifecycleRuleConditions`.
        N)r   r1  r4  ry   )rL   r|   rv   r2  r*   r*   r1   $add_lifecycle_set_storage_class_rule  s    
z+Bucket.add_lifecycle_set_storage_class_rulec                 K   s(   t | j}|tf i | || _dS )aT  Add a "abort incomplete multipart upload" rule to lifecycle rules.

        .. note::
          The "age" lifecycle condition is the only supported condition
          for this rule.

        This defines a [lifecycle configuration](https://cloud.google.com/storage/docs/lifecycle),
        which is set on the bucket. For the general format of a lifecycle configuration, see the
        [bucket resource representation for JSON](https://cloud.google.com/storage/docs/json_api/v1/buckets).

        :type kw: dict
        :params kw: arguments passed to :class:`LifecycleRuleConditions`.
        N)r   r1  r4  r}   r5  r*   r*   r1   4add_lifecycle_abort_incomplete_multipart_upload_rule	  s    
z;Bucket.add_lifecycle_abort_incomplete_multipart_upload_ruler   c                 C   s   | j S )ar  Retrieve location configured for this bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets and
        https://cloud.google.com/storage/docs/locations

        Returns ``None`` if the property has not been set before creation,
        or if the bucket's resource has not been loaded from the server.
        :rtype: str or ``NoneType``
        )	_locationrb   r*   r*   r1   r   	  s    zBucket.locationc                 C   s   t jttdd || _dS )a  (Deprecated) Set `Bucket.location`

        This can only be set at bucket **creation** time.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets and
        https://cloud.google.com/storage/docs/bucket-locations

        .. warning::

            Assignment to 'Bucket.location' is deprecated, as it is only
            valid before the bucket is created. Instead, pass the location
            to `Bucket.create`.
        r   r   N)r   r   _LOCATION_SETTER_MESSAGEr   r9  r   r*   r*   r1   r   "	  s    c                 C   s   | j di }|dS )a  Retrieve the list of regional locations for custom dual-region buckets.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets and
        https://cloud.google.com/storage/docs/locations

        Returns ``None`` if the property has not been set before creation,
        if the bucket's resource has not been loaded from the server,
        or if the bucket is not a dual-regions bucket.
        :rtype: list of str or ``NoneType``
        ZcustomPlacementConfigZdataLocationsr   )rL   Zcustom_placement_configr*   r*   r1   data_locations4	  s    zBucket.data_locationsc                 C   s   | j dS )a  Retrieve the location type for the bucket.

        See https://cloud.google.com/storage/docs/storage-classes

        :getter: Gets the the location type for this bucket.

        :rtype: str or ``NoneType``
        :returns:
            If set, one of
            :attr:`~google.cloud.storage.constants.MULTI_REGION_LOCATION_TYPE`,
            :attr:`~google.cloud.storage.constants.REGION_LOCATION_TYPE`, or
            :attr:`~google.cloud.storage.constants.DUAL_REGION_LOCATION_TYPE`,
            else ``None``.
        ZlocationTyper   rb   r*   r*   r1   location_typeC	  s    zBucket.location_typec                 C   s   | j d}t|S )a#  Return info about access logging for this bucket.

        See https://cloud.google.com/storage/docs/access-logs#status

        :rtype: dict or None
        :returns: a dict w/ keys, ``logBucket`` and ``logObjectPrefix``
                  (if logging is enabled), or None (if not).
        loggingr  r+  r*   r*   r1   get_loggingU	  s    	zBucket.get_logging c                 C   s   ||d}|  d| dS )a7  Enable access logging for this bucket.

        See https://cloud.google.com/storage/docs/access-logs

        :type bucket_name: str
        :param bucket_name: name of bucket in which to store access logs

        :type object_prefix: str
        :param object_prefix: prefix for access log filenames
        )Z	logBucketZlogObjectPrefixr=  Nr   )rL   r   Zobject_prefixr,  r*   r*   r1   enable_logginga	  s    
zBucket.enable_loggingc                 C   s   |  dd dS )zyDisable access logging for this bucket.

        See https://cloud.google.com/storage/docs/access-logs#disabling
        r=  Nr   rb   r*   r*   r1   disable_loggingo	  s    zBucket.disable_loggingc                 C   s    | j d}|durt|S dS )a/  Retrieve the metageneration for the bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: int or ``NoneType``
        :returns: The metageneration of the bucket or ``None`` if the bucket's
                  resource has not been loaded from the server.
        metagenerationNr   r,   int)rL   rB  r*   r*   r1   rB  v	  s    
zBucket.metagenerationc                 C   s   t | jdS )a1  Retrieve info about the owner of the bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: dict or ``NoneType``
        :returns: Mapping of owner's role/ID. Returns ``None`` if the bucket's
                  resource has not been loaded from the server.
        owner)r  r  r   r,   rb   r*   r*   r1   rE  	  s    
zBucket.ownerc                 C   s    | j d}|durt|S dS )aN  Retrieve the number of the project to which the bucket is assigned.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: int or ``NoneType``
        :returns: The project number that owns the bucket or ``None`` if
                  the bucket's resource has not been loaded from the server.
        ZprojectNumberNrC  )rL   project_numberr*   r*   r1   rF  	  s    
zBucket.project_numberc                 C   s2   | j d}|dur.|d}|dur.t|S dS )a"  Retrieve the effective time of the bucket's retention policy.

        :rtype: datetime.datetime or ``NoneType``
        :returns: point-in time at which the bucket's retention policy is
                  effective, or ``None`` if the property is not
                  set locally.
        retentionPolicyNZeffectiveTimer   r,   r   )rL   r  	timestampr*   r*   r1   retention_policy_effective_time	  s
    	
z&Bucket.retention_policy_effective_timec                 C   s"   | j d}|dur|dS dS )a  Retrieve whthere the bucket's retention policy is locked.

        :rtype: bool
        :returns: True if the bucket's policy is locked, or else False
                  if the policy is not locked, or the property is not
                  set locally.
        rG  NisLockedr   )rL   r  r*   r*   r1   retention_policy_locked	  s    	zBucket.retention_policy_lockedc                 C   s2   | j d}|dur.|d}|dur.t|S dS )a"  Retrieve or set the retention period for items in the bucket.

        :rtype: int or ``NoneType``
        :returns: number of seconds to retain items after upload or release
                  from event-based lock, or ``None`` if the property is not
                  set locally.
        rG  NretentionPeriodrC  )rL   r  Zperiodr*   r*   r1   retention_period	  s
    	
zBucket.retention_periodc                 C   s8   | j di }|dur$t||d< nd}| d| dS )a  Set the retention period for items in the bucket.

        :type value: int
        :param value:
            number of seconds to retain items after upload or release from
            event-based lock.

        :raises ValueError: if the bucket's retention policy is locked.
        rG  NrM  )r   r   r  r   )rL   r   r  r*   r*   r1   rN  	  s
    c                 C   s   | j dS )a   Retrieve the URI for the bucket.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: str or ``NoneType``
        :returns: The self link for the bucket or ``None`` if
                  the bucket's resource has not been loaded from the server.
        ZselfLinkr   rb   r*   r*   r1   	self_link	  s    
zBucket.self_linkc                 C   s   | j dS )a  Retrieve or set the storage class for the bucket.

        See https://cloud.google.com/storage/docs/storage-classes

        :setter: Set the storage class for this bucket.
        :getter: Gets the the storage class for this bucket.

        :rtype: str or ``NoneType``
        :returns:
            If set, one of
            :attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`,
            or
            :attr:`~google.cloud.storage.constants.DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS`,
            else ``None``.
        r{   r   rb   r*   r*   r1   r|   	  s    zBucket.storage_classc                 C   s   |  d| dS )a  Set the storage class for the bucket.

        See https://cloud.google.com/storage/docs/storage-classes

        :type value: str
        :param value:
            One of
            :attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
            :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`,
            or
            :attr:`~google.cloud.storage.constants.DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS`,
        r{   Nr   r   r*   r*   r1   r|   	  s    c                 C   s    | j d}|durt|S dS )ax  Retrieve the timestamp at which the bucket was created.

        See https://cloud.google.com/storage/docs/json_api/v1/buckets

        :rtype: :class:`datetime.datetime` or ``NoneType``
        :returns: Datetime object parsed from RFC3339 valid timestamp, or
                  ``None`` if the bucket's resource has not been loaded
                  from the server.
        ZtimeCreatedNrH  r   r*   r*   r1   time_created
  s    zBucket.time_createdc                 C   s   | j di }|ddS )a]  Is versioning enabled for this bucket?

        See  https://cloud.google.com/storage/docs/object-versioning for
        details.

        :setter: Update whether versioning is enabled for this bucket.
        :getter: Query whether versioning is enabled for this bucket.

        :rtype: bool
        :returns: True if enabled, else False.
        
versioningr   Fr   rL   rQ  r*   r*   r1   versioning_enabled"
  s    zBucket.versioning_enabledc                 C   s   |  ddt|i dS )zEnable versioning for this bucket.

        See  https://cloud.google.com/storage/docs/object-versioning for
        details.

        :type value: convertible to boolean
        :param value: should versioning be enabled for the bucket?
        rQ  r   Nr   r   r   r*   r*   r1   rS  2
  s    
c                 C   s   | j di }|ddS )a  Does the requester pay for API requests for this bucket?

        See https://cloud.google.com/storage/docs/requester-pays for
        details.

        :setter: Update whether requester pays for this bucket.
        :getter: Query whether requester pays for this bucket.

        :rtype: bool
        :returns: True if requester pays for API requests for the bucket,
                  else False.
        billingrequesterPaysFr   rR  r*   r*   r1   requester_pays>
  s    zBucket.requester_paysc                 C   s   |  ddt|i dS )a  Update whether requester pays for API requests for this bucket.

        See https://cloud.google.com/storage/docs/using-requester-pays for
        details.

        :type value: convertible to boolean
        :param value: should requester pay for API requests for the bucket?
        rU  rV  NrT  r   r*   r*   r1   rW  O
  s    
c                 C   s   | j di }|ddS )aW  Whether Autoclass is enabled for this bucket.

        See https://cloud.google.com/storage/docs/using-autoclass for details.

        :setter: Update whether autoclass is enabled for this bucket.
        :getter: Query whether autoclass is enabled for this bucket.

        :rtype: bool
        :returns: True if enabled, else False.
        	autoclassr   Fr   )rL   rX  r*   r*   r1   autoclass_enabled[
  s    zBucket.autoclass_enabledc                 C   s   |  ddt|i dS )a  Enable or disable Autoclass at the bucket-level.

        See https://cloud.google.com/storage/docs/using-autoclass for details.

        :type value: convertible to boolean
        :param value: If true, enable Autoclass for this bucket.
                      If false, disable Autoclass for this bucket.

        .. note::
          To enable autoclass, you must set it at bucket creation time.
          Currently, only patch requests that disable autoclass are supported.

        rX  r   NrT  r   r*   r*   r1   rY  j
  s    c                 C   s2   | j d}|dur.|d}|dur.t|S dS )a  Retrieve the toggle time when Autoclaass was last enabled or disabled for the bucket.
        :rtype: datetime.datetime or ``NoneType``
        :returns: point-in time at which the bucket's autoclass is toggled, or ``None`` if the property is not set locally.
        rX  NZ
toggleTimerH  )rL   rX  rI  r*   r*   r1   autoclass_toggle_time{
  s
    
zBucket.autoclass_toggle_timec                 C   s   ||d}|  d| dS )a  Configure website-related properties.

        See https://cloud.google.com/storage/docs/static-website

        .. note::
          This configures the bucket's website-related properties,controlling how
          the service behaves when accessing bucket contents as a web site.
          See [tutorials](https://cloud.google.com/storage/docs/hosting-static-website) and
          [code samples](https://cloud.google.com/storage/docs/samples/storage-define-bucket-website-configuration#storage_define_bucket_website_configuration-python)
          for more information.

        :type main_page_suffix: str
        :param main_page_suffix: The page to use as the main page
                                 of a directory.
                                 Typically something like index.html.

        :type not_found_page: str
        :param not_found_page: The file to use when a page isn't found.
        )ZmainPageSuffixZnotFoundPageZwebsiteNr   )rL   Zmain_page_suffixZnot_found_pager   r*   r*   r1   configure_website
  s    
zBucket.configure_websitec                 C   s   |  ddS )zDisable the website configuration for this bucket.

        This is really just a shortcut for setting the website-related
        attributes to ``None``.
        N)r[  rb   r*   r*   r1   disable_website
  s    zBucket.disable_websitec                 C   sX   |  |}i }| jdur"| j|d< |dur2||d< |j| j d|||dd}t|S )a~  Retrieve the IAM policy for the bucket.

        See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/buckets/getIamPolicy)
        and a [code sample](https://cloud.google.com/storage/docs/samples/storage-view-bucket-iam-members#storage_view_bucket_iam_members-python).

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :type requested_policy_version: int or ``NoneType``
        :param requested_policy_version: (Optional) The version of IAM policies to request.
                                         If a policy with a condition is requested without
                                         setting this, the server will return an error.
                                         This must be set to a value of 3 to retrieve IAM
                                         policies containing conditions. This is to prevent
                                         client code that isn't aware of IAM conditions from
                                         interpreting and modifying policies incorrectly.
                                         The service might return a policy with version lower
                                         than the one that was requested, based on the
                                         feature syntax in the policy fetched.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`google.api_core.iam.Policy`
        :returns: the policy instance, based on the resource returned from
                  the ``getIamPolicy`` API request.
        Nr   ZoptionsRequestedPolicyVersion/iamr   )r   r   r   r   r   r:   )rL   r   Zrequested_policy_versionr   r   r   r,  r*   r*   r1   get_iam_policy
  s    ,



zBucket.get_iam_policyc           	      C   s`   |  |}i }| jdur"| j|d< | j d}| }| j|d< |j|||||dd}t|S )a  Update the IAM policy for the bucket.

        See
        https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy

        If :attr:`user_project` is set, bills the API request to that project.

        :type policy: :class:`google.api_core.iam.Policy`
        :param policy: policy instance used to update bucket's IAM policy.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: :class:`google.api_core.iam.Policy`
        :returns: the policy instance, based on the resource returned from
                  the ``setIamPolicy`` API request.
        Nr   r]  Z
resourceIdr   )r   r   r   Zto_api_reprZ_put_resourcer   r:   )	rL   r  r   r   r   r   r   r_   r,  r*   r*   r1   set_iam_policy
  s     #



	zBucket.set_iam_policyc                 C   sR   |  |}d|i}| jdur&| j|d< | j d}|j||||dd}|dg S )aN  API call:  test permissions

        See
        https://cloud.google.com/storage/docs/json_api/v1/buckets/testIamPermissions

        If :attr:`user_project` is set, bills the API request to that project.

        :type permissions: list of string
        :param permissions: the permissions to check

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :rtype: list of string
        :returns: the permissions returned by the ``testIamPermissions`` API
                  request.
        permissionsNr   z/iam/testPermissionsr   )r   r   r   r   r,   )rL   r`  r   r   r   r   r   respr*   r*   r1   test_iam_permissions  s    


zBucket.test_iam_permissionsc                 C   s   | j    | j j|||||d |rb| j}|jsB|j||d |   |j|||||d |rt| jd| j	d ||d}	t
|	| j	krd| j	f }
t|
|	D ]"}|j    |j j||d qdS )ai  Update bucket's ACL, granting read access to anonymous users.

        :type recursive: bool
        :param recursive: If True, this will make all blobs inside the bucket
                          public as well.

        :type future: bool
        :param future: If True, this will make all objects created in the
                       future public as well.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.
        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        blob's current metageneration matches the given value.

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            blob's current metageneration does not match the given value.

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises ValueError:
            If ``recursive`` is True, and the bucket contains more than 256
            blobs.  This is to prevent extremely long runtime of this
            method.  For such buckets, iterate over the blobs returned by
            :meth:`list_blobs` and call
            :meth:`~google.cloud.storage.blob.Blob.make_public`
            for each blob.
        r   r   r   fullr   r   r   r   r   zRefusing to make public recursively with more than %d objects. If you actually want to make every object in this bucket public, iterate through the blobs returned by 'Bucket.list_blobs()' and call 'make_public' on each one.N)r   allZ
grant_readr  r   loadedr   r   r   r   r   rI   rL   	recursivefuturer   r   r   r   r   Zdoar   r   r8   r*   r*   r1   make_publicK  sP    1zBucket.make_publicc                 C   s   | j    | j j|||||d |rb| j}|jsB|j||d |   |j|||||d |rt| jd| j	d ||d}	t
|	| j	krd| j	f }
t|
|	D ]"}|j    |j j||d qdS )al  Update bucket's ACL, revoking read access for anonymous users.

        :type recursive: bool
        :param recursive: If True, this will make all blobs inside the bucket
                          private as well.

        :type future: bool
        :param future: If True, this will make all objects created in the
                       future private as well.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

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

        :type if_metageneration_match: long
        :param if_metageneration_match: (Optional) Make the operation conditional on whether the
                                        blob's current metageneration matches the given value.
        :type if_metageneration_not_match: long
        :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
                                            blob's current metageneration does not match the given value.
        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises ValueError:
            If ``recursive`` is True, and the bucket contains more than 256
            blobs.  This is to prevent extremely long runtime of this
            method.  For such buckets, iterate over the blobs returned by
            :meth:`list_blobs` and call
            :meth:`~google.cloud.storage.blob.Blob.make_private`
            for each blob.
        r   rc  rd  r   re  zRefusing to make private recursively with more than %d objects. If you actually want to make every object in this bucket private, iterate through the blobs returned by 'Bucket.list_blobs()' and call 'make_private' on each one.N)r   rf  Zrevoke_readr  r   rg  r   r   r   r   r   rI   rh  r*   r*   r1   make_private  sJ    0zBucket.make_privatec           	      C   s   |  |}|j}t| |du r4t tjdd }|d| jig }t||d}t	
t|d}t	
||}| j|j|d|dd}|S )a  Create a signed upload policy for uploading objects.

        This method generates and signs a policy document. You can use
        [`policy documents`](https://cloud.google.com/storage/docs/xml-api/post-object-forms)
        to allow visitors to a website to upload files to
        Google Cloud Storage without giving them direct write access.
        See a [code sample](https://cloud.google.com/storage/docs/xml-api/post-object-forms#python).

        :type expiration: datetime
        :param expiration: (Optional) Expiration in UTC. If not specified, the
                           policy will expire in 1 hour.

        :type conditions: list
        :param conditions: A list of conditions as described in the
                          `policy documents` documentation.

        :type client: :class:`~google.cloud.storage.client.Client`
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the current bucket.

        :rtype: dict
        :returns: A dictionary of (form field name, form field value) of form
                  fields that should be added to your HTML upload form in order
                  to attach the signature.
        Nr   )hoursr5   )
expirationrX   zutf-8)r5   ZGoogleAccessIdr  	signature)r   _credentialsr	   Zensure_signed_credentialsr   datetime	timedeltar3   r   base64	b64encodejsondumpsencodeZ
sign_bytesZsigner_emaildecode)	rL   rX   rn  r   credentialsZpolicy_documentZencoded_policy_documentro  r   r*   r*   r1   generate_upload_policy	  s&    

zBucket.generate_upload_policyc                 C   s   d| j vrtd| j d}|du r.td|dr@td| |}d| ji}| jdurh| j|d< d	| j d
}|j|d|||| d}| | dS )a  Lock the bucket's retention policy.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the blob's bucket.

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

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`

        :raises ValueError:
            if the bucket has no metageneration (i.e., new or never reloaded);
            if the bucket has no retention policy assigned;
            if the bucket's retention policy is already locked.
        rB  z6Bucket has no retention policy assigned: try 'reload'?rG  NrK  z,Bucket's retention policy is already locked.ZifMetagenerationMatchr   r   z/lockRetentionPolicyr   )	r   rI   r,   r   rB  r   r3   r  r6   )rL   r   r   r   r  r   r   Zapi_responser*   r*   r1   lock_retention_policy?  s*    





zBucket.lock_retention_policyGEThttpc              	   C   s   |du rd}n|dvrt d|	r2d| j d}n|
rBt|
|}nd| j }|	sV|
rZd}|du rr| |}|j}|dkrt}nt}|||||| ||dS )	af  Generates a signed URL for this bucket.

        .. note::

            If you are on Google Compute Engine, you can't generate a signed
            URL using GCE service account. If you'd like to be able to generate
            a signed URL from GCE, you can use a standard service account from a
            JSON file rather than a GCE service account.

        If you have a bucket that you want to allow access to for a set
        amount of time, you can use this method to generate a URL that
        is only valid within a certain time period.

        If ``bucket_bound_hostname`` is set as an argument of :attr:`api_access_endpoint`,
        ``https`` works only if using a ``CDN``.

        :type expiration: Union[Integer, datetime.datetime, datetime.timedelta]
        :param expiration: Point in time when the signed URL should expire. If
                           a ``datetime`` instance is passed without an explicit
                           ``tzinfo`` set,  it will be assumed to be ``UTC``.

        :type api_access_endpoint: str
        :param api_access_endpoint: (Optional) URI base.

        :type method: str
        :param method: The HTTP verb that will be used when requesting the URL.

        :type headers: dict
        :param headers:
            (Optional) Additional HTTP headers to be included as part of the
            signed URLs.  See:
            https://cloud.google.com/storage/docs/xml-api/reference-headers
            Requests using the signed URL *must* pass the specified header
            (name and value) with each request for the URL.

        :type query_parameters: dict
        :param query_parameters:
            (Optional) Additional query parameters to be included as part of the
            signed URLs.  See:
            https://cloud.google.com/storage/docs/xml-api/reference-headers#query

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: (Optional) The client to use.  If not passed, falls back
                       to the ``client`` stored on the blob's bucket.


        :type credentials: :class:`google.auth.credentials.Credentials` or
                           :class:`NoneType`
        :param credentials: The authorization credentials to attach to requests.
                            These credentials identify this application to the service.
                            If none are specified, the client will attempt to ascertain
                            the credentials from the environment.

        :type version: str
        :param version: (Optional) The version of signed credential to create.
                        Must be one of 'v2' | 'v4'.

        :type virtual_hosted_style: bool
        :param virtual_hosted_style:
            (Optional) If true, then construct the URL relative the bucket's
            virtual hostname, e.g., '<bucket-name>.storage.googleapis.com'.

        :type bucket_bound_hostname: str
        :param bucket_bound_hostname:
            (Optional) If pass, then construct the URL relative to the bucket-bound hostname.
            Value cane be a bare or with scheme, e.g., 'example.com' or 'http://example.com'.
            See: https://cloud.google.com/storage/docs/request-endpoints#cname

        :type scheme: str
        :param scheme:
            (Optional) If ``bucket_bound_hostname`` is passed as a bare hostname, use
            this value as the scheme.  ``https`` will work only when using a CDN.
            Defaults to ``"http"``.

        :raises: :exc:`ValueError` when version is invalid.
        :raises: :exc:`TypeError` when expiration is not a valid type.
        :raises: :exc:`AttributeError` if credentials is not an instance
                of :class:`google.auth.credentials.Signing`.

        :rtype: str
        :returns: A signed URL you can use to access the resource
                  until expiration.
        Nv2)r~  Zv4z%'version' must be either 'v2' or 'v4'zhttps://z.storage.googleapis.com/)r_   rn  api_access_endpointmethodr   query_parameters)rI   r3   r   r   rp  r   r   upper)rL   rn  r  r  r   r  r   ry  versionZvirtual_hosted_styleZbucket_bound_hostnamer   r_   helperr*   r*   r1   generate_signed_urlt  s8    b
zBucket.generate_signed_url)NN)N)NNNN)r?  )NN)NN)crf   rg   rh   ri   r   r!   r   r   r   r   r   r   ZSTORAGE_CLASSESr   r    r   Z_LOCATION_TYPESrK   r   rk   r   r6   r   r   r   rj   r   r8   r$   r   r   r%   r   r   r(   r-   r   r   r   r   staticmethodr   r   r   r   r   r   r   r&   r  r   r  r  r  r   Zdefault_event_based_holdr  r   r)  r*  r-  r1  r3  r6  r7  r8  r9  r   r;  r<  r>  r@  rA  rB  rE  rF  rJ  rL  rN  rO  r|   rP  rS  rW  rY  rZ  r[  r\  r^  r'   r_  rb  rk  rl  rz  r{  _API_ACCESS_ENDPOINTr  rl   r*   r*   rY   r1   r   g  sF  
	



    
0

V
F.?5





m
p
(
'
j
S
u
 
 









	
,


























A
9
1
c
]
7
7r   c                 K   s:   |  D ],\}}|durt|| krtd| dqdS )a  
    Raise an error if any generation match argument
    is set and its len differs from the given value.

    :type expected_len: int
    :param expected_len: Expected argument length in case it's set.

    :type generation_match_args: dict
    :param generation_match_args: Lists, which length must be checked.

    :raises: :exc:`ValueError` if any argument set, but has an unexpected length.
    N'z+' length must be the same as 'blobs' length)r%  r   rI   )expected_lenZgeneration_match_argsr3   r   r*   r*   r1   r    s    r  )Kri   rs  r  rq  ru  urllib.parser   r   Zgoogle.api_corer   Zgoogle.cloud._helpersr   r   r   Zgoogle.cloud.exceptionsr   Zgoogle.api_core.iamr   Zgoogle.cloud.storager	   Zgoogle.cloud.storage._helpersr
   r   r   r   r   Zgoogle.cloud.storage._signingr   r   r   Zgoogle.cloud.storage.aclr   r   Zgoogle.cloud.storage.blobr   Zgoogle.cloud.storage.constantsr   r   r   r   r   r   r   r   r   r   r    r!   Z!google.cloud.storage.notificationr#   r$   Zgoogle.cloud.storage.retryr%   r&   r'   r(   r   r   r   r   r:  r  r2   r9   r;   rt   r<   rm   ry   r}   objectr   r   r   r  r*   r*   r*   r1   <module>   s    D"  2                     ,