o
    rj@cU                     @   sv  d Z ddlZddlZddlZddlZddlmZ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six)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   4usr/lib/python3.10/site-packages/botocore/parsers.py__init__      
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 | }|di | jS )Nr   )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   )Zprotocolr   r   r   r         r   c                    s    fdd}|S )Nc                    s.   t |dr|j}|d u rd}n|} | ||S )Ntext )hasattrr   )r   shape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   sL   |d u rt }|| _|d u r| j}|| _d | _| jd ur$| ||| _d S 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r5| |r!| |}n| |r.| ||}|S | ||}n| ||}|rE|j	drE|S t
|trj|	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: %sheaderszResponse body:
%s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_metadatar2   r   r   r   parse   s(   


zResponseParser.parsec                 C   s2   | di  di }| d}|r||d< d S d S )NcontextZchecksumZresponse_algorithmZChecksumAlgorithmr@   )r   rD   rF   Zchecksum_context	algorithmr   r   r   rC     s
   
z.ResponseParser._add_checksum_response_metadatac                 C   s   |d uo
|j ddS )N	exceptionF)metadatar@   )r   r   r   r   r   r;     s   z&ResponseParser._is_modeled_error_shapec                 C   sD   |d dkr d|vs|d d u rdS |d   }|dp| S d S )Nr4   i  r3   Ts   <html>)strip
startswith)r   rD   r3   r   r   r   r9     s   z)ResponseParser._is_generic_error_responsec                 C   s4   t d t|d tj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.r4   r   CodeMessageErrorr6   )r7   r8   strr   moveshttp_client	responsesr@   r   rD   r   r   r   r:   +  s   

z&ResponseParser._do_generic_error_parsec                 C   s   t d| jj )Nz%s._do_parseNotImplementedError	__class__r   r   rD   r   r   r   r   r>   <     zResponseParser._do_parsec                 C      t | jj d)Nz._do_error_parserY   r\   r   r   r   r=   ?  s   zResponseParser._do_error_parsec                 C   r^   )Nz._do_modeled_error_parserY   )r   rD   r   rE   r   r   r   r<   B  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_shapeG  s   
zResponseParser._parse_shapec                 C   s*   g }|j }|D ]}|| || q|S r   )memberappendrd   )r   r   rb   rE   member_shapeitemr   r   r   _handle_listM  s
   zResponseParser._handle_listc                 C      |S r   r   r   r   r1   r   r   r   ra   V  s   zResponseParser._default_handlec                 C   s&   | j }|d d}t|d |||S )NrH   Zoperation_namer3   )r+   r@   r   )r   rD   r   parsernamer   r   r   _create_event_streamY  s   z#ResponseParser._create_event_streamc                 C   s   t |d S Nr   )listr0   r   r   r   _get_first_key^  r   zResponseParser._get_first_keyc                 C   sR   |j r't|dkrd}t||j | |}||jvr'd}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%   rm   rq   membersr7   info)r   r   r1   	error_msgtagmsgr   r   r    _has_unknown_tagged_union_membera  s   

z/ResponseParser._has_unknown_tagged_union_memberc                 C   s   dd|iiS )NZSDK_UNKNOWN_MEMBERrm   r   )r   rw   r   r   r   #_handle_unknown_tagged_union_membert  r   z2ResponseParser._handle_unknown_tagged_union_memberNN)r   r   r   __doc__DEFAULT_ENCODINGr,   r   r)   rG   rC   r;   r9   r:   r>   r=   r<   rd   ri   ra   rn   rq   ry   rz   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-   r[   r   r   r   y  s   zBaseXMLResponseParser.__init__c                 C   s   i }|j }|j}|jdpd}|jdpd}|jdr&t|ts&|g}|D ]+}|D ]"}	| |	}
|
|kr>| ||	}q,|
|krI| ||	}q,td|
 |||< q(|S )Nrm   keyr1   	flattenedzUnknown tag: %s)	r   r1   r?   r@   rA   rp   	_node_tagrd   r%   )r   r   rb   rE   	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   subrw   )r   rb   r   r   r   r     r]   zBaseXMLResponseParser._node_tagc                    s*   |j drt|ts|g}t ||S )Nr   )r?   r@   rA   rp   r   ri   )r   r   rb   r   r   r   ri     s   z"BaseXMLResponseParser._handle_listc                 C   s  i }|j }|jddr| |}| |}| ||r&| |}| |S |D ]]}|| }d|jv s9|jdr:q(| 	||}	||	}
|
d urR| 
||
||< q(|jdri }|jd }|j D ]\}}| j|dd d |}|||< qd||v r|| ||< q(|S )	NrK   FlocationeventheaderZxmlAttributerm   :r   )rt   rL   r@   _get_error_root_build_name_to_xml_nodery   rq   rz   r?   _member_key_namerd   Zattribitemsr   r   split)r   r   rb   rE   rt   xml_dictrw   member_namerg   Zxml_nameZmember_nodeZattribsZlocation_namer   r1   Znew_keyr   r   r   _handle_structure  s@   









z'BaseXMLResponseParser._handle_structurec                 C   s2   |  |dkr|D ]}|  |dkr|  S q	|S )NZErrorResponserS   r   )r   original_rootchildr   r   r   r     s   z%BaseXMLResponseParser._get_error_rootc                 C   sL   |j dkr|jdr|jjd}|d ur|S |jd}|d ur$|S |S )Nrp   r   rm   )r`   r?   r@   re   )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 ]'}| |}||v r3t || tr*|| | q|| |g||< q|||< q|S ro   )rA   rp   r   r   rf   )r   Zparent_noder   rh   r   r   r   r   r     s   


z-BaseXMLResponseParser._build_name_to_xml_nodec              
   C   sV   zt jt  | jd}|| | }W |S  ty* } ztd||f d }~ww )N)targetencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed:
%s)r   Z	XMLParserZTreeBuilderr}   feedcloser   r%   )r   
xml_stringrl   rooter   r   r   _parse_xml_string_to_dom  s   


z.BaseXMLResponseParser._parse_xml_string_to_domc                 C   sB   |  D ]\}}t|r| |}| |||< q|j||< q|S r   )r   rp   r   _replace_nodesr   )r   rE   r   r1   Zsub_dictr   r   r   r      s   
z$BaseXMLResponseParser._replace_nodesc                 C   s   |dkrdS dS )NtrueTFr   r   r   r   r   r   r   _handle_boolean	  s   z%BaseXMLResponseParser._handle_booleanc                 C      t |S r   )floatr   r   r   r   _handle_float     z#BaseXMLResponseParser._handle_floatc                 C   
   |  |S r   r(   r   r   r   r   _handle_timestamp     
z'BaseXMLResponseParser._handle_timestampc                 C   r   r   intr   r   r   r   _handle_integer  r   z%BaseXMLResponseParser._handle_integerc                 C   rj   r   r   r   r   r   r   _handle_string  s   z$BaseXMLResponseParser._handle_stringc                 C   r   r   r*   r   r   r   r   _handle_blob   r   z"BaseXMLResponseParser._handle_blobr{   )r   r   r   r   r   r   ri   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   r~   x  s4    
$	





r~   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|v r||d d|v r,d|di|d< |S )Nr3   Errors	RequestIdr6   )r   r   r   r   pop)r   rD   r   xml_contentsr   rE   r   r   r   r=   *  s   


zQueryParser._do_error_parsec                 C      | j ||ddS )NFinject_metadata_parse_body_as_xmlr\   r   r   r   r<   :  r]   z#QueryParser._do_modeled_error_parsec                 C   r   )NTr   r   r\   r   r   r   r>   =  r]   zQueryParser._do_parseTc                 C   s^   |d }|  |}i }|d ur%|}d|jv r| |jd |}| ||}|r-| || |S )Nr3   ZresultWrapper)r   r?   _find_result_wrapped_shaperd   _inject_response_metadata)r   rD   r   r   r   r   rE   startr   r   r   r   @  s   


zQueryParser._parse_body_as_xmlc                 C   s   |  |}|| S r   )r   )r   Zelement_nameZxml_root_nodemappingr   r   r   r   O  s   
z&QueryParser._find_result_wrapped_shapec                 C   sR   |  |}|d}|d ur'|  |}| D ]	\}}|j||< q||d< d S d S Nr6   )r   r@   r   r   )r   rb   inject_intor   
child_nodeZsub_mappingr   r1   r   r   r   r   S  s   


z%QueryParser._inject_response_metadataN)T)	r   r   r   r=   r<   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   s2   |  |}|d}|d urd|ji|d< d S d S )NZ	requestIdr   r6   )r   r@   r   )r   rb   r   r   r   r   r   r   r   ^  s
   

z(EC2QueryParser._inject_response_metadatac                    s,   t  ||}d|v rd|di|d< |S )NZ	RequestIDr   r6   )r   r=   r   )r   rD   r   originalr   r   r   r=   d  s
   
zEC2QueryParser._do_error_parsec                 C   s@   |D ]}|  |dkr|D ]}|  |dkr|    S qq|S )Nr   rS   r   )r   r   r   Zerrors_childr   r   r   r   x  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	|}|S |j}|d u rd S i }| ||r$| |}| |S |D ] }|| }|jd|}||}	|	d urF| || |	||< q&|S )Nrm   )Zis_document_typert   ry   rq   rz   r?   r@   rd   )
r   r   r1   final_parsedmember_shapesrw   r   rg   Z	json_nameZ	raw_valuer   r   r   r     s*   


z BaseJSONParser._handle_structurec           	      C   sF   i }|j }|j}| D ]\}}| ||}| ||}|||< q|S r   )r   r1   r   rd   )	r   r   r1   rE   r   r   r   Z
actual_keyZactual_valuer   r   r   r     s   
zBaseJSONParser._handle_mapc                 C   r   r   r   rk   r   r   r   r     r   zBaseJSONParser._handle_blobc                 C   r   r   r   rk   r   r   r   r     r   z BaseJSONParser._handle_timestampc                 C   s   |  |d }dddi d}|d|dd|d d< |d}|d	|o*t|}|d urBd
|v r<|d
dd }||d d< | ||d  |S )Nr3   r   rQ   rP   rR   messagerQ   rS   r4   Z__type#rr   rP   r2   )_parse_body_as_jsonr@   rT   rsplitr   )r   rD   r   r3   errorZresponse_codecoder   r   r   r=     s   	
zBaseJSONParser._do_error_parsec                 C   s$   d|v r|d | di d< d S d S )Nx-amzn-requestidr6   r   )
setdefault)r   rE   r2   r   r   r   r     s
   z(BaseJSONParser._inject_response_metadatac                 C   s@   |si S | | j}zt|}|W S  ty   d|i Y S w )Nr   )decoder}   jsonloads
ValueError)r   body_contentsr3   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   sj   i }|j dr!|d d}|j|}|r| ||||< |S | |||j| | |||j| |S )Nr5   r2   z:event-type)r?   r@   rt   r>   _parse_non_payload_attrs_parse_payload)r   rD   r   r   Z
event_typeZevent_shaper   r   r   r>     s   
zBaseEventStreamParser._do_parsec              	   C   s   |d  d}|j |}|d ur/| |d }| ||}d|| d| dddi}|S d|d  d	d|d  d
ddi}|S )Nr2   z:exception-typer3   rS   rQ   r   r   rO   z:error-codez:error-message)r@   rt   _initial_body_parserd   )r   rD   r   Zexception_typeZexception_shaper   r3   r   r   r   r   r=     s"   z%BaseEventStreamParser._do_error_parsec                 C   s   |j drS|D ]6}|| }|j dr>|d }|jdkr |}n|jdkr,|| j}n| |}	| ||	}|||<  d S q| |d }
| ||
}|| d S d S )NeventZeventpayloadr3   blobstring)r?   r@   r`   r   r}   r   rd   r   )r   rD   r   r   r   rm   rg   r3   Zparsed_bodyZ	raw_parser   body_parsedr   r   r   r      s(   


z$BaseEventStreamParser._parse_payloadc           	      C   sZ   |d }|D ]$}|| }|j dr*||v r*|| }|jdkr&| |d }|||< qd S )Nr2   r   	timestampg     @@)r?   r@   r`   r(   )	r   rD   r   r   r   r2   rm   rg   r1   r   r   r   r     s   
z.BaseEventStreamParser._parse_non_payload_attrsc                 C      t dNr   rZ   r   r   r   r   r   r   %     z)BaseEventStreamParser._initial_body_parseN)r   r   r   r>   r=   r   r   r   r   r   r   r   r     s    r   c                   @      e Zd Zdd ZdS )EventStreamJSONParserc                 C   
   |  |S r   r   r   r   r   r   r   .  r   z)EventStreamJSONParser._initial_body_parseNr   r   r   r   r   r   r   r   r   -      r   c                   @   r   )EventStreamXMLParserc                 C      |st dS | |S r   r   ZElementr   r   r   r   r   r   r   3     

z(EventStreamXMLParser._initial_body_parseNr   r   r   r   r   r   2  r   r   c                   @   s2   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 ur|j }|r| |||}n| |d |}| ||d  |S )Nr3   r2   )Zevent_stream_name_handle_event_stream_handle_json_bodyr   )r   rD   r   rE   
event_namer   r   r   r>   ?  s   zJSONParser._do_parsec                 C   s   |  |d |S )Nr3   )r   r\   r   r   r   r<   J  r]   z"JSONParser._do_modeled_error_parsec           	      C   sX   |j | }| ||}z| }W n ty   d}t|w | |j|}|||< |S )Nz,First event was not of type initial-response)rt   rn   Zget_initial_responser   r%   r   payload)	r   rD   r   r   Zevent_stream_shapeZevent_streamr   rv   rE   r   r   r   r   M  s   
zJSONParser._handle_event_streamc                 C   s   |  |}| ||S r   )r   rd   )r   Zraw_bodyr   Zparsed_jsonr   r   r   r   Y  s   
zJSONParser._handle_json_bodyN)	r   r   r   r   r,   r>   r<   r   r   r   r   r   r   r   9  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   rD   r   r   r   r   r   r>   b  s   zBaseRestParser._do_parsec                 C   s6   |d u r|S |j }| |||| | |||| d S r   )rt   r   r   )r   rD   r   r   r   r   r   r   r   j  s   z!BaseRestParser._add_modeled_parsec                 C   s   i }|  ||| |S r   )r   r   r   r   r   r<   s  s   z&BaseRestParser._do_modeled_error_parsec                 C   sL   i }|d }d|v r|d |d< |S d|v r$|d |d< | dd|d< |S )Nr2   r   r   x-amz-request-id
x-amz-id-2r   HostIdrI   )r   rD   rL   r2   r   r   r   r   x  s   z*BaseRestParser._populate_response_metadatac           
      C   s   d|j v rK|j d }|| }|j dr | ||}|||< d S |jdv r:|d }t|tr4|| j}|||< d S | |d }| 	||||< d S | |d }| 	||}	|
|	 d S )Nr   r5   )r   r   r3   )r?   r@   rn   r`   rA   bytesr   r}   r   rd   r   )
r   rD   r   r   r   Zpayload_member_nameZ
body_shaper3   r   r   r   r   r   r     s$   



zBaseRestParser._parse_payloadc           
      C   s   |d }|D ]F}|| }|j d}|d u rq|dkr&| ||d ||< q|dkr3| ||||< q|dkrL|j d|}	|	|v rL| |||	 ||< qd S )Nr2   r   Z
statusCoder4   headerrm   )r?   r@   rd   _parse_header_map)
r   rD   r   r   r   r2   rm   rg   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 )Nrm   r   )r?   r@   lowerrN   rs   )r   r   r2   rE   prefixr  rm   r   r   r   r    s   z BaseRestParser._parse_header_mapc                 C   r   r   r   r   r   r   r   r     r   z"BaseRestParser._initial_body_parsec                 C   s,   |}t |rt|| j}t|}|S r   )r   r.   r/   r   r}   r   r   )r   r   r1   rE   decodedr   r   r   r     s
   
zBaseRestParser._handle_stringc                    s@   |j d}|dkrt|tsdd |dD }t ||S )Nr   r  c                 S   s   g | ]}|  qS r   )rM   ).0r   r   r   r   
<listcomp>  s    z/BaseRestParser._handle_list.<locals>.<listcomp>,)r?   r@   rA   rp   r   r   ri   )r   r   rb   r   r   r   r   ri     s   zBaseRestParser._handle_list)r   r   r   r>   r   r<   r   r   r   r  r   r   ri   r   r   r   r   r   r   a  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   r   r   r   r   r   r   r   r     r   z"RestJSONParser._initial_body_parsec                    s   t  ||}| || |S r   )r   r=   _inject_error_code)r   rD   r   r   r   r   r   r=     s   zRestJSONParser._do_error_parsec                 C   sx   |  |d }d|d v r"|d d }|dd }||d d< d S d|v s*d|v r:|d|dd	|d d< d S d S )
Nr3   zx-amzn-errortyper2   r   r   rS   rP   r   r   )r   r   r@   )r   r   rD   r3   r   r   r   r   r    s    z!RestJSONParser._inject_error_codec                 C   r   r   r   rk   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   r   r   r   r   r   r   r   r     r   z!RestXMLParser._initial_body_parsec                 C   s@   |d rz|  |W S  ty   tjddd Y nw | |S )Nr3   z2Exception caught when parsing error response body:T)exc_info)_parse_error_from_bodyr%   r7   r8   _parse_error_from_http_statusr\   r   r   r   r=     s   

zRestXMLParser._do_error_parsec                 C   sH   t |d tjjj|d dd|d dd|d ddddS )	Nr4   r   rO   r2   r   r   )r   r   rR   )rT   r   rU   rV   rW   r@   rX   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|v r;d|di|d< ddddi}t|| |S )	Nr3   rS   r   r   r   rR   r6   r   )r   r   r   rw   r   r   r	   )r   rD   r   r   rE   rL   defaultr   r   r   r  *  s   






z$RestXMLParser._parse_error_from_bodyc                    s   t  ||}|S r   )r   r   r   r   r   r   r   A  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)'r|   r.   r   loggingr   Zbotocore.compatr   r   r   Zbotocore.eventstreamr   r   Zbotocore.utilsr   r   r	   r
   	getLoggerr   r7   r'   r   r   r$   	Exceptionr%   r&   r~   r   r   r   r   r   r   r   r   r
  r  r   r   r   r   r   <module>   sD   h
 ? 24$YS(xP
