U
    M8Úcd°  ã                   @   sz  d Z ddlZddlZddlZddlZddlZddlmZm	Z	 ddl
mZmZ ddlmZmZmZmZ e e¡ZeZG dd„ dƒZdd	„ Zd
d„ ZG dd„ deƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ de eƒZ!G dd„ de eƒZ"G dd„ deƒZ#G d d!„ d!eƒZ$G d"d#„ d#e$eƒZ%G d$d%„ d%e$eƒZ&eee#e%e&d&œZ'dS )'a­  Response parsers for the various protocol types.

The module contains classes that can take an HTTP response, and given
an output shape, parse the response into a dict according to the
rules in the output shape.

There are many similarities amongst the different protocols with regard
to response parsing, and the code is structured in a way to avoid
code duplication when possible.  The diagram below is a diagram
showing the inheritance hierarchy of the response classes.

::



                                 +--------------+
                                 |ResponseParser|
                                 +--------------+
                                    ^    ^    ^
               +--------------------+    |    +-------------------+
               |                         |                        |
    +----------+----------+       +------+-------+        +-------+------+
    |BaseXMLResponseParser|       |BaseRestParser|        |BaseJSONParser|
    +---------------------+       +--------------+        +--------------+
              ^         ^          ^           ^           ^        ^
              |         |          |           |           |        |
              |         |          |           |           |        |
              |        ++----------+-+       +-+-----------++       |
              |        |RestXMLParser|       |RestJSONParser|       |
        +-----+-----+  +-------------+       +--------------+  +----+-----+
        |QueryParser|                                          |JSONParser|
        +-----------+                                          +----------+


The diagram above shows that there is a base class, ``ResponseParser`` that
contains logic that is similar amongst all the different protocols (``query``,
``json``, ``rest-json``, ``rest-xml``).  Amongst the various services there
is shared logic that can be grouped several ways:

* The ``query`` and ``rest-xml`` both have XML bodies that are parsed in the
  same way.
* The ``json`` and ``rest-json`` protocols both have JSON bodies that are
  parsed in the same way.
* The ``rest-json`` and ``rest-xml`` protocols have additional attributes
  besides body parameters that are parsed the same (headers, query string,
  status code).

This is reflected in the class diagram above.  The ``BaseXMLResponseParser``
and the BaseJSONParser contain logic for parsing the XML/JSON body,
and the BaseRestParser contains logic for parsing out attributes that
come from other parts of the HTTP response.  Classes like the
``RestXMLParser`` inherit from the ``BaseXMLResponseParser`` to get the
XML body parsing logic and the ``BaseRestParser`` to get the HTTP
header/status code/query string parsing.

Additionally, there are event stream parsers that are used by the other parsers
to wrap streaming bodies that represent a stream of events. The
BaseEventStreamParser extends from ResponseParser and defines the logic for
parsing values from the headers and payload of a message from the underlying
binary encoding protocol. Currently, event streams support parsing bodies
encoded as JSON and XML through the following hierarchy.


                                  +--------------+
                                  |ResponseParser|
                                  +--------------+
                                    ^    ^    ^
               +--------------------+    |    +------------------+
               |                         |                       |
    +----------+----------+   +----------+----------+    +-------+------+
    |BaseXMLResponseParser|   |BaseEventStreamParser|    |BaseJSONParser|
    +---------------------+   +---------------------+    +--------------+
                     ^                ^        ^                 ^
                     |                |        |                 |
                     |                |        |                 |
                   +-+----------------+-+    +-+-----------------+-+
                   |EventStreamXMLParser|    |EventStreamJSONParser|
                   +--------------------+    +---------------------+

Return Values
=============

Each call to ``parse()`` returns a dict has this form::

    Standard Response

    {
      "ResponseMetadata": {"RequestId": <requestid>}
      <response keys>
    }

    Error response

    {
      "ResponseMetadata": {"RequestId": <requestid>}
      "Error": {
        "Code": <string>,
        "Message": <string>,
        "Type": <string>,
        <additional keys>
      }
    }

é    N)ÚETreeÚXMLParseError)ÚEventStreamÚNoInitialResponseError)Úis_json_value_headerÚlowercase_dictÚmerge_dictsÚparse_timestampc                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚResponseParserFactoryc                 C   s
   i | _ d S ©N)Ú	_defaults)Úself© r   ú4/tmp/pip-unpacked-wheel-ozje0y8b/botocore/parsers.pyÚ__init__Š   s    zResponseParserFactory.__init__c                 K   s   | j  |¡ dS )aO  Set default arguments when a parser instance is created.

        You can specify any kwargs that are allowed by a ResponseParser
        class.  There are currently two arguments:

            * timestamp_parser - A callable that can parse a timestamp string
            * blob_parser - A callable that can parse a blob type

        N)r   Úupdate)r   Úkwargsr   r   r   Úset_parser_defaults   s    
z)ResponseParserFactory.set_parser_defaultsc                 C   s   t | }|f | jŽS r   )ÚPROTOCOL_PARSERSr   )r   Zprotocol_nameZ
parser_clsr   r   r   Úcreate_parser™   s    z#ResponseParserFactory.create_parserN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r
   ‰   s   r
   c                 C   s   t ƒ  | ¡S r   )r
   r   )Úprotocolr   r   r   r   ž   s    r   c                    s   ‡ fdd„}|S )Nc                    s.   t |dƒr|j}|d kr"d}n|}ˆ | ||ƒS )NÚtextÚ )Úhasattrr   )r   ÚshapeZnode_or_stringr   ©Úfuncr   r   Ú_get_text_content¨   s    
z(_text_content.<locals>._get_text_contentr   )r   r    r   r   r   Ú_text_content¢   s    r!   c                   @   s   e Zd ZdS )ÚResponseParserErrorN)r   r   r   r   r   r   r   r"   ·   s   r"   c                   @   s¢   e Zd ZdZdZdZd&dd„Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ ZdS )'ÚResponseParserao  Base class for response parsing.

    This class represents the interface that all ResponseParsers for the
    various protocols must implement.

    This class will take an HTTP response and a model shape and parse the
    HTTP response into a dictionary.

    There is a single public method exposed: ``parse``.  See the ``parse``
    docstring for more info.

    zutf-8Nc                 C   sH   |d krt }|| _|d kr | j}|| _d | _| jd k	rD|  ||¡| _d S r   )ÚDEFAULT_TIMESTAMP_PARSERÚ_timestamp_parserÚ_default_blob_parserÚ_blob_parserÚ_event_stream_parserÚEVENT_STREAM_PARSER_CLS©r   Ztimestamp_parserZblob_parserr   r   r   r   Ì   s    
 ÿzResponseParser.__init__c                 C   s
   t  |¡S r   )Úbase64Ú	b64decode©r   Úvaluer   r   r   r&   Ù   s    z#ResponseParser._default_blob_parserc                 C   sØ   t  d|d ¡ t  d|d ¡ |d dkrj|  |¡rB|  |¡}qv|  |¡r\|  ||¡}|S |  ||¡}n|  ||¡}|rŠ|j 	d¡rŠ|S t
|tƒrÔ| 	di ¡}|d |d	< |d }t|ƒ|d
< ||d< |  ||¡ |S )a>  Parse the HTTP response given a shape.

        :param response: The HTTP response dictionary.  This is a dictionary
            that represents the HTTP request.  The dictionary must have the
            following keys, ``body``, ``headers``, and ``status_code``.

        :param shape: The model shape describing the expected output.
        :return: Returns a dictionary representing the parsed response
            described by the model.  In addition to the shape described from
            the model, each response will also have a ``ResponseMetadata``
            which contains metadata about the response, which contains at least
            two keys containing ``RequestId`` and ``HTTPStatusCode``.  Some
            responses may populate additional keys, but ``RequestId`` will
            always be present.

        zResponse headers: %rÚheaderszResponse body:
%rÚbodyÚstatus_codei-  ÚeventstreamÚResponseMetadataZHTTPStatusCodeZHTTPHeaders)ÚLOGÚdebugÚ_is_generic_error_responseÚ_do_generic_error_parseÚ_is_modeled_error_shapeÚ_do_modeled_error_parseÚ_do_error_parseÚ	_do_parseÚserializationÚgetÚ
isinstanceÚdictr   Ú_add_checksum_response_metadata)r   Úresponser   ÚparsedÚresponse_metadatar/   r   r   r   Úparseß   s(    


zResponseParser.parsec                 C   s.   |  di ¡  di ¡}|  d¡}|r*||d< d S )NÚcontextZchecksumZresponse_algorithmZChecksumAlgorithm©r=   )r   rA   rC   Zchecksum_contextÚ	algorithmr   r   r   r@     s    
z.ResponseParser._add_checksum_response_metadatac                 C   s   |d k	o|j  dd¡S )NÚ	exceptionF)Úmetadatar=   )r   r   r   r   r   r8     s    z&ResponseParser._is_modeled_error_shapec                 C   sD   |d dkr@d|ks |d d kr$dS |d   ¡ }| d¡p>| S d S )Nr1   iô  r0   Ts   <html>)ÚstripÚ
startswith)r   rA   r0   r   r   r   r6     s
    z)ResponseParser._is_generic_error_responsec                 C   s2   t  d¡ t|d ƒtjj |d d¡dœi dœS )NzlReceived a non protocol specific error response from the service, unable to populate error code and message.r1   r   ©ÚCodeÚMessage©ÚErrorr3   )r4   r5   ÚstrÚhttpÚclientÚ	responsesr=   ©r   rA   r   r   r   r7   ,  s    ÿ
 ÿþùz&ResponseParser._do_generic_error_parsec                 C   s   t d| jj ƒ‚d S )Nz%s._do_parse©ÚNotImplementedErrorÚ	__class__r   ©r   rA   r   r   r   r   r;   =  s    zResponseParser._do_parsec                 C   s   t | jj› dƒ‚d S )Nz._do_error_parserV   rY   r   r   r   r:   @  s    zResponseParser._do_error_parsec                 C   s   t | jj› dƒ‚d S )Nz._do_modeled_error_parserV   )r   rA   r   rB   r   r   r   r9   C  s    ÿz&ResponseParser._do_modeled_error_parsec                 C   s    t | d|j› | jƒ}|||ƒS )NZ_handle_)ÚgetattrÚ	type_nameÚ_default_handle)r   r   ÚnodeÚhandlerr   r   r   Ú_parse_shapeH  s     
 ÿzResponseParser._parse_shapec                 C   s*   g }|j }|D ]}| |  ||¡¡ q|S r   )ÚmemberÚappendr_   )r   r   r]   rB   Úmember_shapeÚitemr   r   r   Ú_handle_listN  s
    zResponseParser._handle_listc                 C   s   |S r   r   ©r   r   r.   r   r   r   r\   W  s    zResponseParser._default_handlec                 C   s&   | j }|d  d¡}t|d |||ƒS )NrE   Zoperation_namer0   )r(   r=   r   )r   rA   r   ÚparserÚnamer   r   r   Ú_create_event_streamZ  s    z#ResponseParser._create_event_streamc                 C   s   t |ƒd S ©Nr   )Úlistr-   r   r   r   Ú_get_first_key_  s    zResponseParser._get_first_keyc                 C   sR   |j rNt|ƒdkr$d}t||j ƒ‚|  |¡}||jkrNd}t || ¡ dS dS )Né   zCInvalid service response: %s must have one and only one member set.zqReceived a tagged union response with member unknown to client: %s. Please upgrade SDK for full response support.TF)Zis_tagged_unionÚlenr"   rg   rk   Úmembersr4   Úinfo)r   r   r.   Ú	error_msgÚtagÚmsgr   r   r   Ú _has_unknown_tagged_union_memberb  s    ÿ

ÿz/ResponseParser._has_unknown_tagged_union_memberc                 C   s   dd|iiS )NZSDK_UNKNOWN_MEMBERrg   r   )r   rq   r   r   r   Ú#_handle_unknown_tagged_union_memberu  s    z2ResponseParser._handle_unknown_tagged_union_member)NN)r   r   r   Ú__doc__ÚDEFAULT_ENCODINGr)   r   r&   rD   r@   r8   r6   r7   r;   r:   r9   r_   rd   r\   rh   rk   rs   rt   r   r   r   r   r#   »   s(   
1	r#   c                       s¾   e Zd Zd"‡ fdd„	Zdd„ Zdd„ Z‡ fdd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Z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ZeZeZ‡  ZS )#ÚBaseXMLResponseParserNc                    s   t ƒ  ||¡ t d¡| _d S )Nz{.*})Úsuperr   ÚreÚcompileÚ_namespace_rer*   ©rX   r   r   r   z  s    zBaseXMLResponseParser.__init__c                 C   s®   i }|j }|j}|j d¡pd}|j d¡p.d}|j d¡rLt|tƒsL|g}|D ]X}|D ]F}	|  |	¡}
|
|kr||  ||	¡}qX|
|kr’|  ||	¡}qXtd|
 ƒ‚qX|||< qP|S )Nrg   Úkeyr.   Ú	flattenedzUnknown tag: %s)	r}   r.   r<   r=   r>   rj   Ú	_node_tagr_   r"   )r   r   r]   rB   Ú	key_shapeÚvalue_shapeZkey_location_nameZvalue_location_nameZkeyval_nodeZsingle_pairZtag_nameZkey_nameZval_namer   r   r   Ú_handle_map~  s"    

z!BaseXMLResponseParser._handle_mapc                 C   s   | j  d|j¡S ©Nr   )r{   Úsubrq   )r   r]   r   r   r   r   “  s    zBaseXMLResponseParser._node_tagc                    s*   |j  d¡rt|tƒs|g}tƒ  ||¡S )Nr~   )r<   r=   r>   rj   rx   rd   )r   r   r]   r|   r   r   rd   –  s    z"BaseXMLResponseParser._handle_listc                 C   s  i }|j }|j dd¡r"|  |¡}|  |¡}|  ||¡rL|  |¡}|  |¡S |D ]º}|| }d|jksP|j d¡rtqP|  	||¡}	| |	¡}
|
d k	r¤|  
||
¡||< qP|j d¡rPi }|jd }|j ¡ D ],\}}| j | d¡d d |¡}|||< qÈ||krP|| ||< qP|S )	NrH   FÚlocationÚeventheaderZxmlAttributerg   ú:r   )rn   rI   r=   Ú_get_error_rootÚ_build_name_to_xml_noders   rk   rt   r<   Ú_member_key_namer_   ÚattribÚitemsr{   r„   Úsplit)r   r   r]   rB   rn   Úxml_dictrq   Úmember_namerb   Zxml_nameZmember_nodeZattribsZlocation_namer}   r.   Znew_keyr   r   r   Ú_handle_structure   sD    



ÿ
þ
 ÿ

 ÿ
z'BaseXMLResponseParser._handle_structurec                 C   s2   |   |¡dkr.|D ]}|   |¡dkr|  S q|S )NZErrorResponserP   ©r   )r   Úoriginal_rootÚchildr   r   r   rˆ   Ä  s
    
z%BaseXMLResponseParser._get_error_rootc                 C   sL   |j dkr0|j d¡r0|jj d¡}|d k	r0|S |j d¡}|d k	rH|S |S )Nrj   r~   rg   )r[   r<   r=   r`   )r   r   r   Zlist_member_serialized_nameZserialized_namer   r   r   rŠ   Ë  s    ÿz&BaseXMLResponseParser._member_key_namec                 C   st   t |tƒr|  |d ¡S i }|D ]N}|  |¡}||krft || tƒrT||  |¡ qn|| |g||< q |||< q |S ri   )r>   rj   r‰   r   ra   )r   Zparent_noderŽ   rc   r}   r   r   r   r‰   Û  s    


z-BaseXMLResponseParser._build_name_to_xml_nodec              
   C   sb   z*t jt  ¡ | jd}| |¡ | ¡ }W n2 tk
r\ } ztd||f ƒ‚W 5 d }~X Y nX |S )N)ÚtargetÚencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed:
%s)r   Ú	XMLParserÚTreeBuilderrv   ÚfeedÚcloser   r"   )r   Ú
xml_stringrf   ÚrootÚer   r   r   Ú_parse_xml_string_to_domò  s     ÿ
þÿz.BaseXMLResponseParser._parse_xml_string_to_domc                 C   sB   |  ¡ D ]4\}}t|ƒr2|  |¡}|  |¡||< q|j||< q|S r   )rŒ   rj   r‰   Ú_replace_nodesr   )r   rB   r}   r.   Zsub_dictr   r   r   rž     s    
z$BaseXMLResponseParser._replace_nodesc                 C   s   |dkrdS dS d S )NÚtrueTFr   ©r   r   r   r   r   r   Ú_handle_boolean
  s    z%BaseXMLResponseParser._handle_booleanc                 C   s   t |ƒS r   )Úfloatr    r   r   r   Ú_handle_float  s    z#BaseXMLResponseParser._handle_floatc                 C   s
   |   |¡S r   ©r%   r    r   r   r   Ú_handle_timestamp  s    z'BaseXMLResponseParser._handle_timestampc                 C   s   t |ƒS r   ©Úintr    r   r   r   Ú_handle_integer  s    z%BaseXMLResponseParser._handle_integerc                 C   s   |S r   r   r    r   r   r   Ú_handle_string  s    z$BaseXMLResponseParser._handle_stringc                 C   s
   |   |¡S r   ©r'   r    r   r   r   Ú_handle_blob!  s    z"BaseXMLResponseParser._handle_blob)NN)r   r   r   r   r‚   r   rd   r   rˆ   rŠ   r‰   r   rž   r!   r¡   r£   r¥   r¨   r©   r«   Z_handle_characterZ_handle_doubleÚ_handle_longÚ__classcell__r   r   r|   r   rw   y  s2   
$	





rw   c                   @   s>   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Zdd„ ZdS )ÚQueryParserc                 C   s\   |d }|   |¡}|  |¡}|  |¡ d|kr>| | d¡¡ d|krXd| d¡i|d< |S )Nr0   ÚErrorsÚ	RequestIdr3   )r   r‰   rž   r   Úpop)r   rA   r   Úxml_contentsr›   rB   r   r   r   r:   +  s    


zQueryParser._do_error_parsec                 C   s   | j ||ddS )NF©Úinject_metadata©Ú_parse_body_as_xmlrY   r   r   r   r9   ;  s    z#QueryParser._do_modeled_error_parsec                 C   s   | j ||ddS )NTr³   rµ   rY   r   r   r   r;   >  s    zQueryParser._do_parseTc                 C   s^   |d }|   |¡}i }|d k	rJ|}d|jkr>|  |jd |¡}|  ||¡}|rZ|  ||¡ |S )Nr0   ZresultWrapper)r   r<   Ú_find_result_wrapped_shaper_   Ú_inject_response_metadata)r   rA   r   r´   r²   r›   rB   Ústartr   r   r   r¶   A  s    

 ÿzQueryParser._parse_body_as_xmlc                 C   s   |   |¡}|| S r   )r‰   )r   Zelement_nameZxml_root_nodeÚmappingr   r   r   r·   P  s    
z&QueryParser._find_result_wrapped_shapec                 C   sN   |   |¡}| d¡}|d k	rJ|   |¡}| ¡ D ]\}}|j||< q.||d< d S ©Nr3   )r‰   r=   rŒ   r   )r   r]   Úinject_intorº   Ú
child_nodeZsub_mappingr}   r.   r   r   r   r¸   T  s    


z%QueryParser._inject_response_metadataN)T)	r   r   r   r:   r9   r;   r¶   r·   r¸   r   r   r   r   r®   *  s   
r®   c                       s,   e Zd Zdd„ Z‡ fdd„Zdd„ Z‡  ZS )ÚEC2QueryParserc                 C   s.   |   |¡}| d¡}|d k	r*d|ji|d< d S )NZ	requestIdr°   r3   )r‰   r=   r   )r   r]   r¼   rº   r½   r   r   r   r¸   _  s    

z(EC2QueryParser._inject_response_metadatac                    s,   t ƒ  ||¡}d|kr(d| d¡i|d< |S )NZ	RequestIDr°   r3   )rx   r:   r±   )r   rA   r   Úoriginalr|   r   r   r:   e  s     ÿzEC2QueryParser._do_error_parsec                 C   s@   |D ]6}|   |¡dkr|D ]}|   |¡dkr|    S qq|S )Nr¯   rP   r‘   )r   r’   r“   Zerrors_childr   r   r   rˆ   y  s    zEC2QueryParser._get_error_root)r   r   r   r¸   r:   rˆ   r­   r   r   r|   r   r¾   ^  s   r¾   c                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚBaseJSONParserc           
      C   s   i }|j r|}n||j}|d kr"d S i }|  ||¡rF|  |¡}|  |¡S |D ]@}|| }|j d|¡}| |¡}	|	d k	rJ|  || |	¡||< qJ|S )Nrg   )Zis_document_typern   rs   rk   rt   r<   r=   r_   )
r   r   r.   Úfinal_parsedÚmember_shapesrq   r   rb   Z	json_nameZ	raw_valuer   r   r   r   ƒ  s(    


 ÿ
z BaseJSONParser._handle_structurec           	      C   sF   i }|j }|j}| ¡ D ](\}}|  ||¡}|  ||¡}|||< q|S r   )r}   r.   rŒ   r_   )	r   r   r.   rB   r€   r   r}   Z
actual_keyZactual_valuer   r   r   r‚   œ  s    
zBaseJSONParser._handle_mapc                 C   s
   |   |¡S r   rª   re   r   r   r   r«   ¦  s    zBaseJSONParser._handle_blobc                 C   s
   |   |¡S r   r¤   re   r   r   r   r¥   ©  s    z BaseJSONParser._handle_timestampc           
      C   sî   |   |d ¡}dddœi dœ}|d }| d| dd¡¡|d d< | d	¡}| d
d¡}| d¡}d }	t|ƒdkr’|d r’|d }	|d |d d< |	d kr®| d|oªt|ƒ¡}	|	d k	rÚd|	krÎ|	 dd¡d }	|	|d d< |  ||d ¡ |S )Nr0   r   ©rN   rM   rO   r/   ÚmessagerN   rP   r1   zx-amzn-query-errorú;é   r   rl   ÚTypeZ__typeú#rM   )Ú_parse_body_as_jsonr=   r   rm   rQ   Úrsplitr¸   )
r   rA   r   r0   Úerrorr/   Zresponse_codeZquery_errorZquery_error_componentsÚcoder   r   r   r:   ¬  s,    	 
ÿ

zBaseJSONParser._do_error_parsec                 C   s    d|kr|d |  di ¡d< d S )Núx-amzn-requestidr3   r°   )Ú
setdefault)r   rB   r/   r   r   r   r¸   Ò  s    ÿz(BaseJSONParser._inject_response_metadatac                 C   sF   |si S |  | j¡}zt |¡}|W S  tk
r@   d|i Y S X d S )NrÄ   )Údecoderv   ÚjsonÚloadsÚ
ValueError)r   Úbody_contentsr0   Úoriginal_parsedr   r   r   rÉ   Ø  s    
z"BaseJSONParser._parse_body_as_jsonN)
r   r   r   r   r‚   r«   r¥   r:   r¸   rÉ   r   r   r   r   rÀ   ‚  s   
&rÀ   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚBaseEventStreamParserc                 C   sh   i }|j  d¡r@|d  d¡}|j |¡}|rd|  ||¡||< n$|  |||j|¡ |  |||j|¡ |S )Nr2   r/   z:event-type)r<   r=   rn   r;   Ú_parse_non_payload_attrsÚ_parse_payload)r   rA   r   rÁ   Z
event_typeZevent_shaper   r   r   r;   æ  s"     ÿ
   ÿzBaseEventStreamParser._do_parsec              	   C   s†   |d   d¡}|j  |¡}|d k	r\|  |d ¡}|  ||¡}d||  d|  dd¡¡dœi}n&d|d   d	d¡|d   d
d¡dœi}|S )Nr/   z:exception-typer0   rP   rN   rÄ   r   rL   z:error-codez:error-message)r=   rn   Ú_initial_body_parser_   )r   rA   r   Zexception_typeZexception_shaperÔ   r0   rË   r   r   r   r:   ö  s     þÿþÿz%BaseEventStreamParser._do_error_parsec                 C   s¦   |j  d¡r¢|D ]l}|| }|j  d¡r|d }|jdkr@|}n.|jdkrX| | j¡}n|  |¡}	|  ||	¡}|||<  d S q|  |d ¡}
|  ||
¡}| |¡ d S )NÚeventZeventpayloadr0   ÚblobÚstring)r<   r=   r[   rÏ   rv   rØ   r_   r   )r   rA   r   rÂ   rÁ   rg   rb   r0   Zparsed_bodyZ	raw_parserÔ   Úbody_parsedr   r   r   r×     s&    


 ÿz$BaseEventStreamParser._parse_payloadc           	      C   sZ   |d }|D ]H}|| }|j  d¡r||kr|| }|jdkrL|  |d ¡}|||< qd S )Nr/   r†   Ú	timestampg     @@)r<   r=   r[   r%   )	r   rA   r   rÂ   rÁ   r/   rg   rb   r.   r   r   r   rÖ   !  s    
z.BaseEventStreamParser._parse_non_payload_attrsc                 C   s   t dƒ‚d S ©NrØ   ©rW   ©r   rÓ   r   r   r   rØ   0  s    z)BaseEventStreamParser._initial_body_parseN)r   r   r   r;   r:   r×   rÖ   rØ   r   r   r   r   rÕ   å  s
   rÕ   c                   @   s   e Zd Zdd„ ZdS )ÚEventStreamJSONParserc                 C   s
   |   |¡S r   ©rÉ   rà   r   r   r   rØ   9  s    z)EventStreamJSONParser._initial_body_parseN©r   r   r   rØ   r   r   r   r   rá   8  s   rá   c                   @   s   e Zd Zdd„ ZdS )ÚEventStreamXMLParserc                 C   s   |st  d¡S |  |¡S rƒ   ©r   ÚElementr   ©r   rš   r   r   r   rØ   >  s    
z(EventStreamXMLParser._initial_body_parseNrã   r   r   r   r   rä   =  s   rä   c                   @   s0   e Zd ZeZdd„ Zdd„ Zdd„ Zdd„ Zd	S )
Ú
JSONParserc                 C   sJ   i }|d k	r6|j }|r&|  |||¡}n|  |d |¡}|  ||d ¡ |S )Nr0   r/   )Zevent_stream_nameÚ_handle_event_streamÚ_handle_json_bodyr¸   )r   rA   r   rB   Ú
event_namer   r   r   r;   J  s    zJSONParser._do_parsec                 C   s   |   |d |¡S )Nr0   )rê   rY   r   r   r   r9   U  s    z"JSONParser._do_modeled_error_parsec           	      C   s^   |j | }|  ||¡}z| ¡ }W n  tk
rB   d}t|ƒ‚Y nX |  |j|¡}|||< |S )Nz,First event was not of type initial-response)rn   rh   Zget_initial_responser   r"   rê   Úpayload)	r   rA   r   rë   Zevent_stream_shapeZevent_streamrÙ   rp   rB   r   r   r   ré   X  s    
zJSONParser._handle_event_streamc                 C   s   |   |¡}|  ||¡S r   )rÉ   r_   )r   Zraw_bodyr   Zparsed_jsonr   r   r   rê   d  s    
zJSONParser._handle_json_bodyN)	r   r   r   rá   r)   r;   r9   ré   rê   r   r   r   r   rè   D  s
   rè   c                       sd   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Z‡ fdd„Z‡  ZS )ÚBaseRestParserc                 C   s$   i }|   |¡|d< |  |||¡ |S r»   )Ú_populate_response_metadataÚ_add_modeled_parse©r   rA   r   rÁ   r   r   r   r;   m  s    ÿzBaseRestParser._do_parsec                 C   s6   |d kr|S |j }|  ||||¡ |  ||||¡ d S r   )rn   rÖ   r×   )r   rA   r   rÁ   rÂ   r   r   r   rï   u  s       ÿz!BaseRestParser._add_modeled_parsec                 C   s   i }|   |||¡ |S r   )rï   rð   r   r   r   r9   ~  s    z&BaseRestParser._do_modeled_error_parsec                 C   sJ   i }|d }d|kr"|d |d< n$d|krF|d |d< |  dd¡|d< |S )Nr/   rÍ   r°   úx-amz-request-idú
x-amz-id-2r   ÚHostIdrF   )r   rA   rI   r/   r   r   r   rî   ƒ  s    z*BaseRestParser._populate_response_metadatac           
      C   s¸   d|j kr|j d }|| }|j  d¡r>|  ||¡}|||< q´|jdkrp|d }t|tƒrf| | j¡}|||< q´|  |d ¡}|  	||¡||< n$|  |d ¡}|  	||¡}	| 
|	¡ d S )Nrì   r2   )rÛ   rÚ   r0   )r<   r=   rh   r[   r>   ÚbytesrÏ   rv   rØ   r_   r   )
r   rA   r   rÂ   rÁ   Zpayload_member_nameZ
body_shaper0   rÔ   rÜ   r   r   r   r×     s&    





 ÿ
zBaseRestParser._parse_payloadc           
      C   s    |d }|D ]Ž}|| }|j  d¡}|d kr0qq|dkrN|  ||d ¡||< q|dkrh|  ||¡||< q|dkr|j  d|¡}	|	|kr|  |||	 ¡||< qd S )Nr/   r…   Z
statusCoder1   Úheaderrg   )r<   r=   r_   Ú_parse_header_map)
r   rA   r   rÂ   rÁ   r/   rg   rb   r…   Úheader_namer   r   r   rÖ   ©  s.     ÿ
 ÿ
 ÿz'BaseRestParser._parse_non_payload_attrsc                 C   sN   i }|j  dd¡ ¡ }|D ].}| ¡  |¡r|t|ƒd … }|| ||< q|S )Nrg   r   )r<   r=   ÚlowerrK   rm   )r   r   r/   rB   Úprefixr÷   rg   r   r   r   rö   Á  s    z BaseRestParser._parse_header_mapc                 C   s   t dƒ‚d S rÞ   rß   rà   r   r   r   rØ   Î  s    z"BaseRestParser._initial_body_parsec                 C   s,   |}t |ƒr(t |¡ | j¡}t |¡}|S r   )r   r+   r,   rÏ   rv   rÐ   rÑ   )r   r   r.   rB   Údecodedr   r   r   r©   Õ  s
    
zBaseRestParser._handle_stringc                    s@   |j  d¡}|dkr2t|tƒs2dd„ | d¡D ƒ}tƒ  ||¡S )Nr…   rõ   c                 S   s   g | ]}|  ¡ ‘qS r   )rJ   )Ú.0rœ   r   r   r   Ú
<listcomp>à  s     z/BaseRestParser._handle_list.<locals>.<listcomp>ú,)r<   r=   r>   rj   r   rx   rd   )r   r   r]   r…   r|   r   r   rd   Ü  s    zBaseRestParser._handle_list)r   r   r   r;   rï   r9   rî   r×   rÖ   rö   rØ   r©   rd   r­   r   r   r|   r   rí   l  s   	rí   c                       s<   e Zd ZeZdd„ Z‡ fdd„Zdd„ Zdd„ ZeZ	‡  Z
S )	ÚRestJSONParserc                 C   s
   |   |¡S r   râ   rà   r   r   r   rØ   è  s    z"RestJSONParser._initial_body_parsec                    s   t ƒ  ||¡}|  ||¡ |S r   )rx   r:   Ú_inject_error_code)r   rA   r   rË   r|   r   r   r:   ë  s    zRestJSONParser._do_error_parsec                 C   sr   |   |d ¡}d|d krB|d d }| d¡d }||d d< n,d|ksRd|krn| d| dd	¡¡|d d< d S )
Nr0   zx-amzn-errortyper/   r‡   r   rP   rM   rÌ   r   )rØ   r   r=   )r   rË   rA   r0   rÌ   r   r   r   rÿ   ð  s    z!RestJSONParser._inject_error_codec                 C   s   t |ƒS r   r¦   re   r   r   r   r¨   ý  s    zRestJSONParser._handle_integer)r   r   r   rá   r)   rØ   r:   rÿ   r¨   r¬   r­   r   r   r|   r   rþ   ä  s   rþ   c                       sD   e Zd ZeZdd„ Zdd„ Zdd„ Zdd„ Ze	‡ fd	d
„ƒZ
‡  ZS )ÚRestXMLParserc                 C   s   |st  d¡S |  |¡S rƒ   rå   rç   r   r   r   rØ     s    
z!RestXMLParser._initial_body_parsec                 C   sB   |d r8z|   |¡W S  tk
r6   tjddd Y nX |  |¡S )Nr0   z2Exception caught when parsing error response body:T)Úexc_info)Ú_parse_error_from_bodyr"   r4   r5   Ú_parse_error_from_http_statusrY   r   r   r   r:     s    þzRestXMLParser._do_error_parsec                 C   sF   t |d ƒtjj |d d¡dœ|d  dd¡|d  dd¡dœdœS )	Nr1   r   rL   r/   rñ   rò   )r°   ró   rO   )rQ   rR   rS   rT   r=   rU   r   r   r   r  '  s    
 ÿþþùz+RestXMLParser._parse_error_from_http_statusc                 C   s’   |d }|   |¡}|  |¡}|  |¡ |jdkr\|  |¡}| dd¡ | dd¡ ||dœS d|krvd| d¡i|d< ddddœi}t||ƒ |S )	Nr0   rP   r°   r   ró   rO   r3   rÃ   )r   r‰   rž   rq   rî   r±   r   )r   rA   r²   r›   rB   rI   Údefaultr   r   r   r  5  s    






z$RestXMLParser._parse_error_from_bodyc                    s   t ƒ  ||¡}|S r   )rx   r©   r    r|   r   r   r©   L  s    zRestXMLParser._handle_string)r   r   r   rä   r)   rØ   r:   r  r  r!   r©   r­   r   r   r|   r   r     s   r   )Zec2ÚqueryrÐ   z	rest-jsonzrest-xml)(ru   r+   Úhttp.clientrR   rÐ   Úloggingry   Zbotocore.compatr   r   Zbotocore.eventstreamr   r   Zbotocore.utilsr   r   r   r	   Ú	getLoggerr   r4   r$   r
   r   r!   Ú	Exceptionr"   r#   rw   r®   r¾   rÀ   rÕ   rá   rä   rè   rí   rþ   r   r   r   r   r   r   Ú<module>   sD   h
 ? 24$cS(xPû