
    G              	          d Z ddlZddlmZ ddlmc mZ ddlmc m	Z
 ddlmZ ddlZddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dgZ G d	 d
 ej4                  d
g d            Z G d de      Z G d de      Zy)z6Library for handling batch HTTP requests for apitools.    N)http_client)urllib_parse)range)
exceptions)http_wrapperBatchApiRequestc                       e Zd ZdZy)RequestResponseAndHandleraO  Container for data related to completing an HTTP request.

    This contains an HTTP request, its response, and a callback for handling
    the response from the server.

    Attributes:
      request: An http_wrapper.Request object representing the HTTP request.
      response: The http_wrapper.Response object returned from the server.
      handler: A callback function accepting two arguments, response
        and exception. Response is an http_wrapper.Response object, and
        exception is an apiclient.errors.HttpError object if an error
        occurred, or otherwise None.
    N)__name__
__module____qualname____doc__     )lib/third_party/apitools/base/py/batch.pyr
   r
   )   s    r   r
   )requestresponsehandlerc                   F    e Zd ZdZ G d de      Z	 	 ddZd	dZ	 	 d
dZy)r   z4Batches multiple api requests into a single request.c                   l    e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
d Zy	)
BatchApiRequest.ApiCalla/  Holds request and response information for each request.

        ApiCalls are ultimately exposed to the client once the HTTP
        batch request has been completed.

        Attributes:
          http_request: A client-supplied http_wrapper.Request to be
              submitted to the server.
          response: A http_wrapper.Response object given by the server as a
              response to the user request, or None if an error occurred.
          exception: An apiclient.errors.HttpError object if an error
              occurred, or None.

        c                     t        t        |t        j                  gz               | _        d| _        || _        || _        || _        d| _	        d| _
        y)ar  Initialize an individual API request.

            Args:
              request: An http_wrapper.Request object.
              retryable_codes: A list of integer HTTP codes that can
                  be retried.
              service: A service inheriting from base_api.BaseApiService.
              method_config: Method config for the desired API request.

            N)listsetr   UNAUTHORIZED_ApiCall__retryable_codes_ApiCall__http_response_ApiCall__service_ApiCall__method_confighttp_request_ApiCall__response_ApiCall__exception)selfr   retryable_codesservicemethod_configs        r   __init__z BatchApiRequest.ApiCall.__init__O   sV     &*O{'?'?&@@A&CD"#'D $DN#0D  'D"DO#Dr   c                     | j                   d uS N)	exceptionr#   s    r   is_errorz BatchApiRequest.ApiCall.is_errore   s    >>--r   c                     | j                   S r)   )r!   r+   s    r   r   z BatchApiRequest.ApiCall.responsei   s    ??"r   c                     | j                   S r)   )r"   r+   s    r   r*   z!BatchApiRequest.ApiCall.exceptionm   s    ###r   c                 l    | j                   xr' | j                   j                  t        j                  k(  S r)   )r   status_coder   r   r+   s    r   authorization_failedz,BatchApiRequest.ApiCall.authorization_failedq   s1    (( N$$00K4L4LLOr   c                 d    | j                   y| j                   j                  }|| j                  vS )NF)r   r0   r   )r#   response_codes     r   terminal_statez&BatchApiRequest.ApiCall.terminal_statev   s3    ##+ 00<<M (>(>>>r   c                     || _         || _        | j                  rC| j                  s6| j                  j	                  | j
                  | j                         | _        yyy)ap  Handles incoming http response to the request in http_request.

            This is intended to be used as a callback function for
            BatchHttpRequest.Add.

            Args:
              http_response: Deserialized http_wrapper.Response object.
              exception: apiclient.errors.HttpError object if an error
                  occurred.

            N)r   r"   r4   r   ProcessHttpResponser   r!   )r#   http_responser*   s      r   HandleResponsez&BatchApiRequest.ApiCall.HandleResponse}   sU     $1D (D""4+;+;"&.."D"D(($*>*>#@ ,<"r   N)r   r   r   r   r'   propertyr,   r   r*   r1   r4   r8   r   r   r   ApiCallr   >   sx    		$, 
	. 
	. 
	# 
	# 
	$ 
	$ 
	O 
	O 
	? 
	?	@r   r:   Nc                 L    g | _         |xs g | _        |xs d| _        || _        y)a  Initialize a batch API request object.

        Args:
          batch_url: Base URL for batch API calls.
          retryable_codes: A list of integer HTTP codes that can be retried.
          response_encoding: The encoding type of response content.
        z https://www.googleapis.com/batchN)api_requestsr$   	batch_urlresponse_encoding)r#   r=   r$   r>   s       r   r'   zBatchApiRequest.__init__   s.     .4""H&H!2r   c                     |j                  |      }|j                  |      }|j                  ||||      }| j                  || j                  ||      }| j
                  j                  |       y)a  Add a request to the batch.

        Args:
          service: A class inheriting base_api.BaseApiService.
          method: A string indicated desired method from the service. See
              the example in the class docstring.
          request: An input message appropriate for the specified
              service.method.
          global_params: Optional additional parameters to pass into
              method.PrepareHttpRequest.

        Returns:
          None

        )global_paramsupload_configN)GetMethodConfigGetUploadConfigPrepareHttpRequestr:   r$   r<   append)	r#   r%   methodr   r@   r&   rA   r    api_requests	            r   AddzBatchApiRequest.Add   sy    "  //7//7 117-' 2 )
 ll$..H  -r   c                 D   | j                   D cg c]  }|j                  s| }}|xs t        |      }t        |      D ]H  }	|	rt	        j
                  |       t        dt        |      |      D ]  }
t        | j                  || j                        }t        j                  ||
|
|z         D ](  }|j                  |j                  |j                         * |j                  |       t        |j                   d      st#        d t        j                  ||
|
|z         D              s|j                   j$                  j'                  |        | j                   D cg c]  }|j                  s| }}|r> | j                   S  | j                   S c c}w c c}w )a  Execute all of the requests in the batch.

        Args:
          http: httplib2.Http object for use in the request.
          sleep_between_polls: Integer number of seconds to sleep between
              polls.
          max_retries: Max retries. Any requests that have not succeeded by
              this number of retries simply report the last response or
              exception, whatever it happened to be.
          max_batch_size: int, if specified requests will be split in batches
              of given size.
          batch_request_callback: function of (http_response, exception) passed
              to BatchHttpRequest which will be run on any given results.

        Returns:
          List of ApiCalls.
        r   )r=   callbackr>   credentialsc              3   4   K   | ]  }|j                     y wr)   )r1   ).0r   s     r   	<genexpr>z*BatchApiRequest.Execute.<locals>.<genexpr>   s%      O+Nw #77+Ns   )r<   r4   lenr   timesleepBatchHttpRequestr=   r>   	itertoolsislicerH   r    r8   Executehasattrr   anyrK   refresh)r#   httpsleep_between_pollsmax_retriesmax_batch_sizebatch_request_callbackr   requests
batch_sizeattemptibatch_http_requests               r   rU   zBatchApiRequest.Execute   s   & ,0+<+< 3+<"11 +< 3#4s8}
[)G

./1c(mZ8 &6"nn3&*&<&<&"
  )//011z> CG&**,,g.D.DF C #**404<<7 O*3*:*:8;<a*n+NO O 0088>% 9* 04/@/@ 0/@G..  /@H 0   = *<    E3:0s   F#F)NNNr)   )   rc   NN)	r   r   r   r   objectr:   r'   rH   rU   r   r   r   r   r   ;   s7    >O@& O@b 8<#'3.< @A<@5!r   c                   T    e Zd ZdZddZd Zed        Zd Zd Z	d Z
dd	Zd
 Zd Zy)rR   zDBatches multiple http_wrapper.Request objects into a single request.Nc                     || _         || _        || _        i | _        t	        j
                         | _        t        j                         | _	        y)a/  Constructor for a BatchHttpRequest.

        Args:
          batch_url: URL to send batch requests to.
          callback: A callback to be called for each response, of the
              form callback(response, exception). The first parameter is
              the deserialized Response object. The second is an
              apiclient.errors.HttpError exception object if an HTTP error
              occurred while processing the request, or None if no error
              occurred.
          response_encoding: The encoding type of response content.
        N)
_BatchHttpRequest__batch_url_BatchHttpRequest__callback$_BatchHttpRequest__response_encoding,_BatchHttpRequest__request_response_handlersrS   count_BatchHttpRequest__last_auto_iduuiduuid4_BatchHttpRequest__base_id)r#   r=   rJ   r>   s       r   r'   zBatchHttpRequest.__init__   sI     % # $5  ,.( (oo/ r   c                 N    d| j                   dt        j                  |      dS )aK  Convert an id to a Content-ID header value.

        Args:
          request_id: String identifier for a individual request.

        Returns:
          A Content-ID header with the id_ encoded into it. A UUID is
          prepended to the value because Content-ID headers are
          supposed to be universally unique.

        <+>)ro   r   quote)r#   
request_ids     r   _ConvertIdToHeaderz#BatchHttpRequest._ConvertIdToHeader  s     !NNL,>,>z,JKKr   c                    | j                  d      s)| j                  d      st        j                  d| z        d| vrt        j                  d| z        | dd j	                  dd      \  }}t        j                  |      S )aw  Convert a Content-ID header value to an id.

        Presumes the Content-ID header conforms to the format that
        _ConvertIdToHeader() returns.

        Args:
          header: A string indicating the Content-ID header value.

        Returns:
          The extracted id value.

        Raises:
          BatchError if the header is not in the expected format.
        rq   rs   z Invalid value for Content-ID: %srr      )
startswithendswithr   
BatchErrorrsplitr   unquote)header_ru   s      r   _ConvertHeaderToIdz#BatchHttpRequest._ConvertHeaderToId%  s      !!#&&//#*>''2V;= =f''2V;= =q++C3:##J//r   c                 D   t        j                  |j                        }t        j                  dd|j                  |j
                  df      }t        |t        j                        s|j                  d      }dj                  |j                  |df      }|j                  j                  dd      j                  d      \  }}t        j                   ||      }|j                  j#                         D ]  \  }}	|dk(  r|	||<    |j$                  |d<   |j'                  d	       |j(                  |j+                  |j(                         t        j,                         }
t/        j0                  |
d
      }|j3                  |d       |
j5                         }||z   S )zConvert a http_wrapper.Request object into a string.

        Args:
          request: A http_wrapper.Request to serialize.

        Returns:
          The request as a string in application/http format.
         zutf-8 z	HTTP/1.1
content-typezapplication/json/HostNr   )maxheaderlenF)unixfrom)r   urlspliturl
urlunsplitpathquery
isinstancesix	text_typedecodejoinhttp_methodheadersgetsplitmime_nonmultipartMIMENonMultipartitemsnetlocset_unixfrombodyset_payloadStringIO	generator	Generatorflattengetvalue)r#   r   parsedrequest_linestatus_linemajorminormsgkeyvaluestr_iogenr   s                r   _SerializeRequestz"BatchHttpRequest._SerializeRequest?  sj    &&w{{3#..V[[&,,35,6'..w7Lii!
 
 **.005c
 	u00> "////1JCn$CH 2
 mmF<<#OOGLL) !!&q9C%( T!!r   c                 $   |j                  dd      \  }}|j                  dd      \  }}}t        j                         }|j                  |      }t	        |      }||d<   |j                         }t        j                  ||| j                        S )zConvert string into Response and content.

        Args:
          payload: Header and body string to be deserialized.

        Returns:
          A Response object
        
rx   r      status)	r   email_parserParserparsestrdictget_payloadr   Responserg   )	r#   payloadr   r   r   parserr   infocontents	            r   _DeserializeResponsez%BatchHttpRequest._DeserializeResponsem  s      '}}T15W"((a061 $$&oog& CyX //#$$T7D4D4DEEr   c                 >    t        t        | j                              S )zCreate a new id.

        Auto incrementing number that avoids conflicts with ids already used.

        Returns:
           A new unique id string.
        )strnextrl   r+   s    r   _NewIdzBatchHttpRequest._NewId  s     4++,--r   c                 X    t        |d|      }|| j                  | j                         <   y)a  Add a new request.

        Args:
          request: A http_wrapper.Request to add to the batch.
          callback: A callback to be called for this response, of the
              form callback(response, exception). The first parameter is the
              deserialized response object. The second is an
              apiclient.errors.HttpError exception object if an HTTP error
              occurred while processing the request, or None if no errors
              occurred.

        Returns:
          None
        N)r
   rj   r   )r#   r   rJ   r   s       r   rH   zBatchHttpRequest.Add  s(     ,GT8D:A((7r   c                    t        j                  d      }t        |dd        | j                  D ]{  }t	        j
                  dd      }d|d<   | j                  |      |d<   | j                  | j                  |   j                        }|j                  |       |j                  |       } t        j                  | j                  d	      }|j                         |_        d
|j!                         z  |j"                  d<   t        j$                  ||      }|j&                  dk\  rt(        j*                  j-                  |      d|j.                  d   z  }|j0                  }	t3        |	t4              r1| j6                  r%|j0                  j9                  | j6                        }	t;        j<                         }
|
j?                  ||	z         }|jA                         st)        jB                  d      |jE                         D ]a  }| jG                  |d         }| jI                  |jE                               }| j                  |   jK                  |      | j                  |<   c y)a=  Serialize batch request, send to server, process response.

        Args:
          http: A httplib2.Http object to be used to make the request with.

        Raises:
          httplib2.HttpLib2Error if a transport error has occured.
          apiclient.errors.BatchError if the response is the wrong format.
        mixed_write_headersc                      y r)   r   r+   s    r   <lambda>z+BatchHttpRequest._Execute.<locals>.<lambda>  s    r   applicationrY   binaryzContent-Transfer-Encodingz
Content-IDPOSTzmultipart/mixed; boundary="%s"r   ,  zcontent-type: %s

z'Response not in multipart/mixed format.)r   N)&mime_multipartMIMEMultipartsetattrrj   r   r   rv   r   r   r   attachr   Requestrg   	as_stringr   get_boundaryr   MakeRequestr0   r   	HttpErrorFromResponser   r   r   bytesri   r   r   r   r   is_multipartr|   r   r   r   _replace)r#   rY   messager   r   r   r   r   r   r   r   mime_responsepartru   s                 r   _ExecutezBatchHttpRequest._Execute  s,    !..w7)+<= 33C#44]FKC/7C+, $ 7 7 <C))005==?DOOD!NN3 4 &&t'7'7@((*,0D0D0F+G'  ++D':3&&&33H== ,hmmN.KK""gu%$*B*B&&--d.F.FGG$$&(89))+''9; ; "--/D00l1CDJ001A1A1CDH 00<EE% F ' ,,Z8 0r   c                 `   | j                  |       | j                  D ]  }| j                  |   j                  }| j                  |   j                  }d}|j                  dk\  rt
        j                  j                  |      }|	 |||       | j                  }| j                  ||        y)a  Execute all the requests as a single batched HTTP request.

        Args:
          http: A httplib2.Http object to be used with the request.

        Returns:
          None

        Raises:
          BatchError if the response is the wrong format.
        Nr   )	r   rj   r   r   r0   r   r   r   rh   )r#   rY   r   r   rJ   r*   s         r   rU   zBatchHttpRequest.Execute  s     	d33C77<EEH77<DDHI##s*&00==hG	#9-*)4 4r   )NNr)   )r   r   r   r   r'   rv   staticmethodr   r   r   r   rH   r   rU   r   r   r   rR   rR      sG    N&@L 0 02,"\F4.B$:(x5r   rR   )r   collectionsemail.generatorr   email.mime.multipartmime	multipartr   email.mime.nonmultipartnonmultipartr   email.parserr   r   rS   rP   rm   r   	six.movesr   r   r   apitools.base.pyr   r   __all__
namedtupler
   rd   r   rR   r   r   r   <module>r      s   " =  # - - 3 3 #    
 ! "  ' ) 
 6 6 6#%G!I $u!f u!pG5v G5r   