a
    !fx                     @   s   d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 ddl	mZ ddlmZ dd	lmZ dd
lmZ G dd deZG dd de
ZdS )z.Create / interact with gcloud storage buckets.    N)_rfc3339_to_datetime)NotFound)Iterator)_PropertyMixin)_scalar_property)	BucketACL)DefaultObjectACLBlobc                       s*   e Zd ZdZd fdd	Zdd Z  ZS )_BlobIteratoraB  An iterator listing blobs in a bucket

    You shouldn't have to use this directly, but instead should use the
    :class:`gcloud.storage.blob.Bucket.list_blobs` method.

    :type bucket: :class:`gcloud.storage.bucket.Bucket`
    :param bucket: The bucket from which to list blobs.

    :type extra_params: dict or None
    :param extra_params: Extra query string parameters for the API call.

    :type client: :class:`gcloud.storage.client.Client`
    :param client: Optional. The client to use for making connections.
                   Defaults to the bucket's client.
    Nc                    sB   |d u r|j }|| _t | _d | _tt| j||jd |d d S )Nz/o)clientpathextra_params)	r   bucketsetprefixes_current_prefixessuperr   __init__r   )selfr   r   r   	__class__ V/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/storage/bucket.pyr   /   s    

z_BlobIterator.__init__c                 c   s^   t |dd| _| j| j |dg D ],}|d}t|| jd}|| |V  q,dS )zYield :class:`.storage.blob.Blob` items from response.

        :type response: dict
        :param response: The JSON API response for a page of blobs.
        r   r   itemsname)r   N)tuplegetr   r   updater
   r   _set_properties)r   responseitemr   blobr   r   r   get_items_from_response9   s    

z%_BlobIterator.get_items_from_response)NN)__name__
__module____qualname____doc__r   r#   __classcell__r   r   r   r   r      s   
r   c                       s  e Zd ZdZeZdZdZdQ fdd	Zdd Z	e
d	d
 ZdRddZdSddZdTddZe
dd Ze
dd Zedd Ze
dd ZdUddZdVddZdWdd ZdXd!d"ZdYd#d$ZdZd%d&Zd[d'd(Ze
d)d* Zejd+d* Ze
d,d- Ze
d.d/ Ze
d0d1 Zejd2d1 Ze d3Z!d4d5 Z"d\d7d8Z#d9d: Z$e
d;d< Z%e
d=d> Z&e
d?d@ Z'e
dAdB Z(e
dCdD Z)e)jdEdD Z)e
dFdG Z*e
dHdI Z+e+jdJdI Z+d]dKdLZ,dMdN Z-d^dOdPZ.  Z/S )_Bucketa:  A class representing a Bucket on Cloud Storage.

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

    :type name: string
    :param name: The name of the bucket.
       )STANDARDZNEARLINEZDURABLE_REDUCED_AVAILABILITYNc                    s0   t t| j|d || _t| | _t| | _d S )Nr   )r   r)   r   _clientr   _aclr   _default_object_acl)r   r   r   r   r   r   r   \   s    
zBucket.__init__c                 C   s
   d| j  S )Nz<Bucket: %s>r,   r   r   r   r   __repr__b   s    zBucket.__repr__c                 C   s   | j S )z The client bound to this bucket.)r-   r0   r   r   r   r   e   s    zBucket.clientc                 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: string
        :param blob_name: The name of the blob to be instantiated.

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

        :rtype: :class:`gcloud.storage.blob.Blob`
        :returns: The blob object created.
        )r   r   
chunk_sizer	   )r   	blob_namer2   r   r   r   r"   j   s    zBucket.blobc                 C   sH   |  |}z$ddi}|jjd| j|dd W dS  tyB   Y dS 0 dS )ap  Determines whether or not this bucket exists.

        :type client: :class:`gcloud.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.

        :rtype: boolean
        :returns: True if the bucket exists in Cloud Storage.
        fieldsr   GETN)methodr   query_params_target_objectTF)_require_client
connectionapi_requestr   r   )r   r   r7   r   r   r   exists~   s    

zBucket.existsc                    sZ     |}d|ji}t fdd jD } j|d< |jjdd|| d} | dS )	a  Creates current bucket.

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

        This implements "storage.buckets.insert".

        :type client: :class:`gcloud.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.
        projectc                 3   s   | ]}| j | fV  qd S N)_properties).0keyr0   r   r   	<genexpr>   s   z Bucket.create.<locals>.<genexpr>r   POSTz/b)r6   r   r7   datar8   N)r9   r=   dictZ_changesr   r:   r;   r   )r   r   r7   
propertiesZapi_responser   r0   r   create   s    


zBucket.createc                 C   s   | j S )zCreate our ACL on demand.)r.   r0   r   r   r   acl   s    z
Bucket.aclc                 C   s   | j S )z&Create our defaultObjectACL on demand.)r/   r0   r   r   r   default_object_acl   s    zBucket.default_object_aclc                 C   s   d|  S )zRelative URL path for a bucket.

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

        :rtype: string
        :returns: The relative URL path for ``bucket_name``.
        z/b/r   )bucket_namer   r   r   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.)r   
ValueErrorrK   r0   r   r   r   r      s    zBucket.pathc                 C   sT   |  |}t| |d}z$|jjd|j|d}|| |W S  tyN   Y dS 0 dS )aS  Get a blob object by name.

        This will return None if the blob doesn't exist::

          >>> from gcloud import storage
          >>> client = storage.Client()
          >>> bucket = client.get_bucket('my-bucket')
          >>> print bucket.get_blob('/path/to/blob.txt')
          <Blob: my-bucket, /path/to/blob.txt>
          >>> print bucket.get_blob('/does-not-exist.txt')
          None

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

        :type client: :class:`gcloud.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.

        :rtype: :class:`gcloud.storage.blob.Blob` or None
        :returns: The blob object if it exists, otherwise None.
        r   r   r5   r6   r   r8   N)r9   r
   r:   r;   r   r   r   )r   r3   r   r"   r    r   r   r   get_blob   s    

zBucket.get_blobnoAclc	                 C   s~   i }	|dur||	d< |dur$||	d< |dur4||	d< |durD||	d< ||	d< |dur\||	d< | j | |	|d}
|durz||
_|
S )	a  Return an iterator used to find blobs in the bucket.

        :type max_results: integer or ``NoneType``
        :param max_results: maximum number of blobs to return.

        :type page_token: string
        :param page_token: opaque marker for the next "page" of blobs. If not
                           passed, will return the first page of blobs.

        :type prefix: string or ``NoneType``
        :param prefix: optional prefix used to filter blobs.

        :type delimiter: string or ``NoneType``
        :param delimiter: optional delimter, used with ``prefix`` to
                          emulate hierarchy.

        :type versions: boolean or ``NoneType``
        :param versions: whether object versions should be returned as
                         separate blobs.

        :type projection: string or ``NoneType``
        :param projection: If used, must be 'full' or 'noAcl'. Defaults to
                           'noAcl'. Specifies the set of properties to return.

        :type fields: string or ``NoneType``
        :param fields: 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 language of each blob returned:
                       'items/contentLanguage,nextPageToken'

        :type client: :class:`gcloud.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.

        :rtype: :class:`_BlobIterator`.
        :returns: An iterator of blobs.
        NZ
maxResultsprefix	delimiterversions
projectionr4   )r   r   )_iterator_classZnext_page_token)r   max_resultsZ
page_tokenrQ   rR   rS   rT   r4   r   r   resultr   r   r   
list_blobs   s$    )zBucket.list_blobsFc                 C   st   |  |}|r\t| j| jd |d}t|| jkrHd| jf }t|| j|dd |d |jjd| 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:`gcloud.exceptions.NotFound`.  If the bucket is not empty
        (and ``force=False``), will raise :class:`gcloud.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.

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

        :type client: :class:`gcloud.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.

        :raises: :class:`ValueError` if ``force`` is ``True`` and the bucket
                 contains more than 256 objects / blobs.
           )rV   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 r>   r   )r"   r   r   r   <lambda>_      zBucket.delete.<locals>.<lambda>)on_errorr   DELETENrN   )
r9   listrX   _MAX_OBJECTS_FOR_ITERATIONlenrL   delete_blobsr:   r;   r   )r   forcer   blobsmessager   r   r   delete6  s"    
zBucket.deletec                 C   s.   |  |}t| j|}|jjd|dd dS )a  Deletes a blob from the current bucket.

        If the blob isn't found (backend 404), raises a
        :class:`gcloud.exceptions.NotFound`.

        For example::

          >>> from gcloud.exceptions import NotFound
          >>> from gcloud import storage
          >>> client = storage.Client()
          >>> bucket = client.get_bucket('my-bucket')
          >>> print bucket.list_blobs()
          [<Blob: my-bucket, my-file.txt>]
          >>> bucket.delete_blob('my-file.txt')
          >>> try:
          ...   bucket.delete_blob('doesnt-exist')
          ... except NotFound:
          ...   pass

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

        :type client: :class:`gcloud.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.

        :raises: :class:`gcloud.exceptions.NotFound` (to suppress
                 the exception, call ``delete_blobs``, passing a no-op
                 ``on_error`` callback, e.g.::

                 >>> bucket.delete_blobs([blob], on_error=lambda blob: None)
        r]   NrN   )r9   r
   rK   r   r:   r;   )r   r3   r   Z	blob_pathr   r   r   delete_blobh  s
    !

zBucket.delete_blobc              	   C   s^   |D ]T}z(|}t |tjs |j}| j||d W q tyV   |durP|| n Y q0 qdS )aX  Deletes a list of blobs from the current bucket.

        Uses :func:`Bucket.delete_blob` to delete each individual blob.

        :type blobs: list of string or :class:`gcloud.storage.blob.Blob`
        :param blobs: A list of blob names or Blob objects to delete.

        :type on_error: a callable taking (blob)
        :param on_error: If not ``None``, called once for each blob raising
                         :class:`gcloud.exceptions.NotFound`;
                         otherwise, the exception is propagated.

        :type client: :class:`gcloud.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.

        :raises: :class:`gcloud.exceptions.NotFound` (if
                 `on_error` is not passed).
        r   N)
isinstancesixstring_typesr   rf   r   )r   rc   r\   r   r"   r3   r   r   r   ra     s    
zBucket.delete_blobsc                 C   sT   |  |}|du r|j}t||d}|jd |j }|jjd||d}|| |S )a  Copy the given blob to the given bucket, optionally with a new name.

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

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

        :type new_name: string
        :param new_name: (optional) the new name for the copied file.

        :type client: :class:`gcloud.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.

        :rtype: :class:`gcloud.storage.blob.Blob`
        :returns: The new Blob.
        NrM   z/copyTorC   rN   )r9   r   r
   r   r:   r;   r   )r   r"   Zdestination_bucketnew_namer   new_blobZapi_pathZcopy_resultr   r   r   	copy_blob  s    

zBucket.copy_blobc                 C   s"   | j || ||d}|j|d |S )ax  Rename the given blob using copy and delete operations.

        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.

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

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

        :type client: :class:`gcloud.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.

        :rtype: :class:`Blob`
        :returns: The newly-renamed blob.
        rg   )rm   re   )r   r"   rk   r   rl   r   r   r   rename_blob  s    zBucket.rename_blobc                 C   s   dd | j ddD S )a  Retrieve CORS policies configured for this bucket.

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

        :rtype: list of dictionaries
        :returns: A sequence of mappings describing each CORS policy.
        c                 S   s   g | ]}t |qS r   copydeepcopy)r@   policyr   r   r   
<listcomp>  s   zBucket.cors.<locals>.<listcomp>corsr   r?   r   r0   r   r   r   rt     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.
        rt   N_patch_property)r   entriesr   r   r   rt     s    
c                 C   s   | j dS )a?  Retrieve the ETag for the bucket.

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

        :rtype: string or ``NoneType``
        :returns: The bucket etag or ``None`` if the property is not
                  set locally.
        etagru   r0   r   r   r   ry     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: string or ``NoneType``
        :returns: The ID of the bucket or ``None`` if the property is not
                  set locally.
        idru   r0   r   r   r   rz     s    
z	Bucket.idc                 C   s$   | j di }dd |ddD S )a"  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

        :rtype: list(dict)
        :returns: A sequence of mappings describing each lifecycle rule.
        	lifecyclec                 S   s   g | ]}t |qS r   ro   )r@   ruler   r   r   rs   *  r[   z*Bucket.lifecycle_rules.<locals>.<listcomp>r|   r   ru   r   infor   r   r   lifecycle_rules  s    
zBucket.lifecycle_rulesc                 C   s   |  dd|i d S )Nr{   r|   rv   )r   rulesr   r   r   r   ,  s    locationc                 C   s   | j d}t|S )a#  Return info about access logging for this bucket.

        See: https://cloud.google.com/storage/docs/accesslogs#status

        :rtype: dict or None
        :returns: a dict w/ keys, ``logBucket`` and ``logObjectPrefix``
                  (if logging is enabled), or None (if not).
        logging)r?   r   rp   rq   r}   r   r   r   get_logging;  s    	zBucket.get_logging c                 C   s   ||d}|  d| dS )aF  Enable access logging for this bucket.

        See: https://cloud.google.com/storage/docs/accesslogs#delivery

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

        :type object_prefix: string
        :param object_prefix: prefix for access log filenames
        )Z	logBucketZlogObjectPrefixr   Nrv   )r   rJ   Zobject_prefixr~   r   r   r   enable_loggingG  s    
zBucket.enable_loggingc                 C   s   |  dd dS )zyDisable access logging for this bucket.

        See: https://cloud.google.com/storage/docs/accesslogs#disabling
        r   Nrv   r0   r   r   r   disable_loggingU  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: integer or ``NoneType``
        :returns: The metageneration of the bucket or ``None`` if the property
                  is not set locally.
        metagenerationNr?   r   int)r   r   r   r   r   r   \  s    
zBucket.metagenerationc                 C   s   t | jdS )a  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. If the property is not set
                  locally, returns ``None``.
        owner)rp   rq   r?   r   r0   r   r   r   r   j  s    
zBucket.ownerc                 C   s    | j d}|durt|S dS )a9  Retrieve the number of the project to which the bucket is assigned.

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

        :rtype: integer or ``NoneType``
        :returns: The project number that owns the bucket or ``None`` if the
                  property is not set locally.
        ZprojectNumberNr   )r   project_numberr   r   r   r   v  s    
zBucket.project_numberc                 C   s   | j dS )a
  Retrieve the URI for the bucket.

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

        :rtype: string or ``NoneType``
        :returns: The self link for the bucket or ``None`` if the property is
                  not set locally.
        ZselfLinkru   r0   r   r   r   	self_link  s    
zBucket.self_linkc                 C   s   | j dS )a  Retrieve the storage class for the bucket.

        See: https://cloud.google.com/storage/docs/storage-classes
        https://cloud.google.com/storage/docs/nearline-storage
        https://cloud.google.com/storage/docs/durable-reduced-availability

        :rtype: string or ``NoneType``
        :returns: If set, one of "STANDARD", "NEARLINE", or
                  "DURABLE_REDUCED_AVAILABILITY", else ``None``.
        storageClassru   r0   r   r   r   storage_class  s    zBucket.storage_classc                 C   s(   || j vrtd|f | d| dS )a  Set the storage class for the bucket.

        See: https://cloud.google.com/storage/docs/storage-classes
        https://cloud.google.com/storage/docs/nearline-storage
        https://cloud.google.com/storage/docs/durable-reduced-availability

        :type value: string
        :param value: one of "STANDARD", "NEARLINE", or
                      "DURABLE_REDUCED_AVAILABILITY"
        zInvalid storage class: %sr   N)_STORAGE_CLASSESrL   rw   r   valuer   r   r   r     s    
c                 C   s    | j d}|durt|S dS )aM  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 property is not set locally.
        ZtimeCreatedN)r?   r   r   r   r   r   r   time_created  s    
zBucket.time_createdc                 C   s   | j di }|ddS )zIs versioning enabled for this bucket?

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

        :rtype: boolean
        :returns: True if enabled, else False.
        
versioningenabledFru   )r   r   r   r   r   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 anabled for the bucket?
        r   r   N)rw   boolr   r   r   r   r     s    
c                 C   s   ||d}|  d| dS )a  Configure website-related properties.

        See: https://developers.google.com/storage/docs/website-configuration

        .. note::
          This (apparently) only works
          if your bucket name is a domain name
          (and to do that, you need to get approved somehow...).

        If you want this bucket to host a website, just provide the name
        of an index page and a page to use when a blob isn't found::

          >>> from gcloud import storage
          >>> client = storage.Client()
          >>> bucket = client.get_bucket(bucket_name)
          >>> bucket.configure_website('index.html', '404.html')

        You probably should also make the whole bucket public::

          >>> bucket.make_public(recursive=True, future=True)

        This says: "Make the bucket public, and all the stuff already in
        the bucket, and anything else I add to the bucket.  Just make it
        all public."

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

        :type not_found_page: string
        :param not_found_page: The file to use when a page isn't found.
        )ZmainPageSuffixZnotFoundPageZwebsiteNrv   )r   Zmain_page_suffixZnot_found_pagerD   r   r   r   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   r0   r   r   r   disable_website  s    zBucket.disable_websitec                 C   s   | j    | j j|d |rP| j}|js8|j|d |   |j|d |rt| jd| j	d |d}t
|| j	krd| j	f }t||D ] }|j    |j j|d qdS )a  Make a bucket public.

        If ``recursive=True`` and the bucket contains more than 256
        objects / blobs this will cowardly refuse to make the objects public.
        This is to prevent extremely long runtime of this method.

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

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

        :type client: :class:`gcloud.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.
        rg   fullrY   )rT   rV   r   zRefusing to make public recursively with more than %d objects. If you actually want to make every object in this bucket public, please do it on the objects yourself.N)rH   allZ
grant_readsaverI   Zloadedreloadr^   rX   r_   r`   rL   )r   	recursivefuturer   Zdoarc   rd   r"   r   r   r   make_public  s,    zBucket.make_public)N)N)N)N)N)NNNNNrP   NN)FN)N)NN)NN)N)r   )NN)FFN)0r$   r%   r&   r'   r   rU   r_   r   r   r1   propertyr   r"   r<   rG   rH   rI   staticmethodrK   r   rO   rX   re   rf   ra   rm   rn   rt   setterry   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r(   r   r   r   r   r)   H   s   	








%   
D
2
)
   


















(r)   )r'   rp   ri   Zgcloud._helpersr   Zgcloud.exceptionsr   Zgcloud.iteratorr   Zgcloud.storage._helpersr   r   Zgcloud.storage.aclr   r   Zgcloud.storage.blobr
   r   r)   r   r   r   r   <module>   s   )