B ç0œ`=¥ã@szdZddlZddlZddlZddlZddlmZmZmZddl m Z m Z ddl m Z mZmZmZe e¡Ze ZGdd„deƒZdd „Zd d „ZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZ Gdd„de eƒZ!Gdd„de eƒZ"Gdd„deƒZ#Gd d!„d!eƒZ$Gd"d#„d#e$eƒZ%Gd$d%„d%e$eƒZ&eee#e%e&d&œZ'dS)'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": } } Error response { "ResponseMetadata": {"RequestId": } "Error": { "Code": , "Message": , "Type": , } } éN)ÚsixÚETreeÚ XMLParseError)Ú EventStreamÚNoInitialResponseError)Úparse_timestampÚ merge_dictsÚis_json_value_headerÚlowercase_dictc@s$eZdZdd„Zdd„Zdd„ZdS)ÚResponseParserFactorycCs i|_dS)N)Ú _defaults)Úself©rúk/private/var/folders/sf/wxz_36012wxg_prv29r6623x5vlqx8/T/pip-target-tft40_m7/lib/python/botocore/parsers.pyÚ__init__†szResponseParserFactory.__init__cKs|j |¡dS)aOSet 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 timetsamp string * blob_parser - A callable that can parse a blob type N)r Úupdate)r ÚkwargsrrrÚset_parser_defaults‰s z)ResponseParserFactory.set_parser_defaultscCst|}|f|jŽS)N)ÚPROTOCOL_PARSERSr )r Z protocol_nameZ parser_clsrrrÚ create_parser•sz#ResponseParserFactory.create_parserN)Ú__name__Ú __module__Ú __qualname__rrrrrrrr …s r cCs tƒ |¡S)N)r r)Úprotocolrrrršsrcs‡fdd„}|S)Ncs.t|dƒr|j}|dkr"d}n|}ˆ|||ƒS)NÚtextÚ)Úhasattrr)r ÚshapeZnode_or_stringr)ÚfuncrrÚ_get_text_content¤s  z(_text_content.._get_text_contentr)rrr)rrÚ _text_contentžs r c@s eZdZdS)ÚResponseParserErrorN)rrrrrrrr!²sr!c@s‚eZdZdZdZdZddd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„ZdS)ÚResponseParseraoBase 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. zutf-8NcCsH|dkr t}||_|dkr |j}||_d|_|jdk rD| ||¡|_dS)N)ÚDEFAULT_TIMESTAMP_PARSERÚ_timestamp_parserÚ_default_blob_parserÚ _blob_parserÚ_event_stream_parserÚEVENT_STREAM_PARSER_CLS)r Útimestamp_parserÚ blob_parserrrrrÆs zResponseParser.__init__cCs t |¡S)N)Úbase64Ú b64decode)r Úvaluerrrr%Òsz#ResponseParser._default_blob_parsercCsÌt d|d¡t d|d¡|ddkrj| |¡rB| |¡}qv| |¡r\| ||¡}|S| ||¡}n | ||¡}|rŠ|j  d¡rŠ|St |t ƒrÈ|  di¡}|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. zResponse headers: %sÚheaderszResponse body: %sÚbodyÚ status_codei-Ú eventstreamÚResponseMetadataZHTTPStatusCodeZ 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 )r ÚresponserÚparsedZresponse_metadatar.rrrÚparseØs&          zResponseParser.parsecCs|dk o|j dd¡S)NÚ exceptionF)Úmetadatar<)r rrrrr7sz&ResponseParser._is_modeled_error_shapecCsD|ddkr@d|ks |ddkr$dS|d ¡}| d¡p>| SdS)Nr0iôr/Ts)ÚstripÚ startswith)r r?r/rrrr5 s  z)ResponseParser._is_generic_error_responsecCs4t d¡t|dƒtjjj |dd¡dœidœS)NzlReceived a non protocol specific error response from the service, unable to populate error code and message.r0r)ÚCodeÚMessage)ÚErrorr2)r3r4ÚstrrÚmovesÚ http_clientÚ responsesr<)r r?rrrr6s    z&ResponseParser._do_generic_error_parsecCstd|jjƒ‚dS)Nz %s._do_parse)ÚNotImplementedErrorÚ __class__r)r r?rrrrr:*szResponseParser._do_parsecCstd|jjƒ‚dS)Nz%s._do_error_parse)rMrNr)r r?rrrrr9-szResponseParser._do_error_parsecCstd|jjƒ‚dS)Nz%s._do_modeled_error_parse)rMrNr)r r?rr@rrrr81sz&ResponseParser._do_modeled_error_parsecCst|d|j|jƒ}|||ƒS)Nz _handle_%s)ÚgetattrÚ type_nameÚ_default_handle)r rÚnodeÚhandlerrrrÚ _parse_shape5s zResponseParser._parse_shapecCs.g}|j}x|D]}| | ||¡¡qW|S)N)ÚmemberÚappendrT)r rrRr@Ú member_shapeÚitemrrrÚ _handle_list:s  zResponseParser._handle_listcCs|S)Nr)r rr-rrrrQCszResponseParser._default_handlecCs&|j}|d d¡}t|d|||ƒS)NÚcontextZoperation_namer/)r'r<r)r r?rÚparserÚnamerrrÚ_create_event_streamFsz#ResponseParser._create_event_stream)NN)rrrÚ__doc__ÚDEFAULT_ENCODINGr(rr%rAr7r5r6r:r9r8rTrYrQr]rrrrr"¶s   0  r"cs¾eZdZd"‡fdd„ Zdd„Zdd„Z‡fdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z e dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe d d!„ƒZeZeZeZ‡ZS)#ÚBaseXMLResponseParserNcs"tt|ƒ ||¡t d¡|_dS)Nz{.*})Úsuperr`rÚreÚcompileÚ _namespace_re)r r)r*)rNrrrMs zBaseXMLResponseParser.__init__c Cs¶i}|j}|j}|j d¡pd}|j d¡p.d}|j d¡rLt|tƒsL|g}xd|D]\}xN|D]F} | | ¡} | |kr€| || ¡} q\| |kr–| || ¡} q\td| ƒ‚q\W| || <qRW|S)Nr\Úkeyr-Ú flattenedzUnknown tag: %s) rer-r;r<r=ÚlistÚ _node_tagrTr!) r rrRr@Ú key_shapeÚ value_shapeZkey_location_nameZvalue_location_nameZ keyval_nodeZ single_pairZtag_nameZkey_nameZval_namerrrÚ _handle_mapRs"    z!BaseXMLResponseParser._handle_mapcCs|j d|j¡S)Nr)rdÚsubÚtag)r rRrrrrhgszBaseXMLResponseParser._node_tagcs.|j d¡rt|tƒs|g}tt|ƒ ||¡S)Nrf)r;r<r=rgrar`rY)r rrR)rNrrrYjsz"BaseXMLResponseParser._handle_listcCsøi}|j}|j dd¡r"| |¡}| |¡}xÆ|D]¾}||}d|jks2|j d¡rVq2| ||¡}| |¡} | dk r†| || ¡||<q2|j d¡r2i} |jd} x:|j  ¡D],\} } |j   |   d¡dd| ¡}| | |<q¬W| | kr2| | ||<q2W|S) NrBFÚlocationÚ eventheaderZ xmlAttributer\ú:r) ÚmembersrCr<Ú_get_error_rootÚ_build_name_to_xml_noder;Ú_member_key_namerTÚattribÚitemsrdrlÚsplit)r rrRr@rqÚxml_dictÚ member_namerWZxml_nameZ member_nodeZattribsZ location_namerer-Znew_keyrrrÚ_handle_structurets2          z'BaseXMLResponseParser._handle_structurecCs2| |¡dkr.x|D]}| |¡dkr|SqW|S)NZ ErrorResponserH)rh)r Ú original_rootÚchildrrrrr‘s  z%BaseXMLResponseParser._get_error_rootcCsL|jdkr0|j d¡r0|jj d¡}|dk r0|S|j d¡}|dk rH|S|S)Nrgrfr\)rPr;r<rU)r rryZlist_member_serialized_nameZserialized_namerrrrt˜s z&BaseXMLResponseParser._member_key_namecCsxt|tƒr| |d¡Si}xV|D]N}| |¡}||krht||tƒrV|| |¡qp|||g||<q"|||<q"W|S)Nr)r=rgrsrhrV)r Z parent_noderxrXrerrrrs§s    z-BaseXMLResponseParser._build_name_to_xml_nodec Csby*tjt ¡|jd}| |¡| ¡}Wn2tk r\}ztd||fƒ‚Wdd}~XYnX|S)N)ÚtargetÚencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed: %s)rÚ XMLParserÚ TreeBuilderr_ÚfeedÚcloserr!)r Ú xml_stringr[ÚrootÚerrrÚ_parse_xml_string_to_dom¾s   z.BaseXMLResponseParser._parse_xml_string_to_domcCsFx@| ¡D]4\}}t|ƒr4| |¡}| |¡||<q |j||<q W|S)N)rvrgrsÚ_replace_nodesr)r r@rer-Zsub_dictrrrr‡Ìs  z$BaseXMLResponseParser._replace_nodescCs|dkr dSdSdS)NÚtrueTFr)r rrrrrÚ_handle_booleanÕsz%BaseXMLResponseParser._handle_booleancCst|ƒS)N)Úfloat)r rrrrrÚ _handle_floatÜsz#BaseXMLResponseParser._handle_floatcCs | |¡S)N)r$)r rrrrrÚ_handle_timestampàsz'BaseXMLResponseParser._handle_timestampcCst|ƒS)N)Úint)r rrrrrÚ_handle_integeräsz%BaseXMLResponseParser._handle_integercCs|S)Nr)r rrrrrÚ_handle_stringèsz$BaseXMLResponseParser._handle_stringcCs | |¡S)N)r&)r rrrrrÚ _handle_blobìsz"BaseXMLResponseParser._handle_blob)NN)rrrrrkrhrYrzrrrtrsr†r‡r r‰r‹rŒrŽrrZ_handle_characterZ_handle_doubleZ _handle_longÚ __classcell__rr)rNrr`Ls&       r`c@s>eZdZdd„Zdd„Zdd„Zddd „Zd d „Zd d „ZdS)Ú QueryParsercCs\|d}| |¡}| |¡}| |¡d|kr>| | d¡¡d|krXd| d¡i|d<|S)Nr/ÚErrorsÚ RequestIdr2)r†rsr‡rÚpop)r r?rÚ xml_contentsr„r@rrrr9÷s   zQueryParser._do_error_parsecCs|j||ddS)NF)Úinject_metadata)Ú_parse_body_as_xml)r r?rrrrr8sz#QueryParser._do_modeled_error_parsecCs|j||ddS)NT)r—)r˜)r r?rrrrr: szQueryParser._do_parseTcCs^|d}| |¡}i}|dk rJ|}d|jkr>| |jd|¡}| ||¡}|rZ| ||¡|S)Nr/Z resultWrapper)r†r;Ú_find_result_wrapped_shaperTÚ_inject_response_metadata)r r?rr—r–r„r@Ústartrrrr˜ s    zQueryParser._parse_body_as_xmlcCs| |¡}||S)N)rs)r Z element_nameZ xml_root_nodeÚmappingrrrr™s z&QueryParser._find_result_wrapped_shapecCsR| |¡}| d¡}|dk rN| |¡}x| ¡D]\}}|j||<q0W||d<dS)Nr2)rsr<rvr)r rRÚ inject_intorœÚ child_nodeZ sub_mappingrer-rrrrš s   z%QueryParser._inject_response_metadataN)T) rrrr9r8r:r˜r™ršrrrrr’õs  r’cs,eZdZdd„Z‡fdd„Zdd„Z‡ZS)ÚEC2QueryParsercCs.| |¡}| d¡}|dk r*d|ji|d<dS)NZ requestIdr”r2)rsr<r)r rRrrœržrrrrš,s  z(EC2QueryParser._inject_response_metadatacs0tt|ƒ ||¡}d|kr,d| d¡i|d<|S)NZ RequestIDr”r2)rarŸr9r•)r r?rÚoriginal)rNrrr92s zEC2QueryParser._do_error_parsecCs@x:|D]2}| |¡dkrx|D]}| |¡dkr|SqWqW|S)Nr“rH)rh)r r{r|Z errors_childrrrrrFs    zEC2QueryParser._get_error_root)rrrršr9rrr‘rr)rNrrŸ*s rŸc@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)ÚBaseJSONParserc Csd|j}|dkrdSi}xH|D]@}||}|j d|¡}| |¡}|dk r| |||¡||<qW|S)Nr\)rqr;r<rT) r rr-Ú member_shapesÚ final_parsedryrWZ json_nameZ raw_valuerrrrzQs  z BaseJSONParser._handle_structurec CsJi}|j}|j}x4| ¡D](\}}| ||¡}| ||¡}|||<qW|S)N)rer-rvrT) r rr-r@rirjreZ actual_keyZ actual_valuerrrrkcs   zBaseJSONParser._handle_mapcCs | |¡S)N)r&)r rr-rrrrmszBaseJSONParser._handle_blobcCs | |¡S)N)r$)r rr-rrrrŒpsz BaseJSONParser._handle_timestampcCs˜| |d¡}dddœidœ}| d| dd¡¡|dd<| d¡}| d |oTt|ƒ¡}|dk r„d |krx| d d ¡d }||dd <| ||d ¡|S)Nr/r)rGrF)rHr2ÚmessagerGrHr0Z__typeú#érFr.)Ú_parse_body_as_jsonr<rIÚrsplitrš)r r?rr/ÚerrorZ response_codeÚcoderrrr9ss   zBaseJSONParser._do_error_parsecCs d|kr|d| di¡d<dS)Nzx-amzn-requestidr2r”)Ú setdefault)r r@r.rrrršŽsz(BaseJSONParser._inject_response_metadatacCs@|siS| |j¡}yt |¡}|Stk r:d|iSXdS)Nr¤)Údecoder_ÚjsonÚloadsÚ ValueError)r Ú body_contentsr/Úoriginal_parsedrrrr§“s  z"BaseJSONParser._parse_body_as_jsonN) rrrrzrkrrŒr9ršr§rrrrr¡Os r¡c@s4eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd S) ÚBaseEventStreamParsercCshi}|j d¡r@|d d¡}|j |¡}|rd| ||¡||<n$| |||j|¡| |||j|¡|S)Nr1r.z :event-type)r;r<rqr:Ú_parse_non_payload_attrsÚ_parse_payload)r r?rr£Z event_typeZ event_shaperrrr:¢s   zBaseEventStreamParser._do_parsec Cs†|d d¡}|j |¡}|dk r\| |d¡}| ||¡}d|| d| dd¡¡dœi}n&d|d d d¡|d d d¡dœi}|S) Nr.z:exception-typer/rHrGr¤r)rFrGz :error-codez:error-message)r<rqÚ_initial_body_parserT)r r?rZexception_typeZexception_shaper±r/r©rrrr9¯s  z%BaseEventStreamParser._do_error_parsec Cs¨|j d¡r¤xr|D]j}||}|j d¡r|d}|jdkrB|}n.|jdkrZ| |j¡}n| |¡} | || ¡}|||<dSqW| |d¡} | || ¡} | | ¡dS)NÚeventZ eventpayloadr/ÚblobÚstring)r;r<rPr¬r_rµrTr) r r?rr¢r£r\rWr/Z parsed_bodyZ raw_parser±Ú body_parsedrrrr´Äs         z$BaseEventStreamParser._parse_payloadc Cs^|d}xP|D]H}||}|j d¡r||kr||}|jdkrN| |d¡}|||<qWdS)Nr.roÚ timestampg@@)r;r<rPr$) r r?rr¢r£r.r\rWr-rrrr³Øs   z.BaseEventStreamParser._parse_non_payload_attrscCs tdƒ‚dS)Nrµ)rM)r r°rrrrµæsz)BaseEventStreamParser._initial_body_parseN)rrrr:r9r´r³rµrrrrr² s  r²c@seZdZdd„ZdS)ÚEventStreamJSONParsercCs | |¡S)N)r§)r r°rrrrµðsz)EventStreamJSONParser._initial_body_parseN)rrrrµrrrrr»îsr»c@seZdZdd„ZdS)ÚEventStreamXMLParsercCs|st d¡S| |¡S)Nr)rÚElementr†)r rƒrrrrµös z(EventStreamXMLParser._initial_body_parseN)rrrrµrrrrr¼ôsr¼c@s0eZdZeZdd„Zdd„Zdd„Zdd„Zd S) Ú JSONParsercCsJi}|dk r6|j}|r&| |||¡}n| |d|¡}| ||d¡|S)Nr/r.)Zevent_stream_nameÚ_handle_event_streamÚ_handle_json_bodyrš)r r?rr@Ú event_namerrrr:szJSONParser._do_parsecCs| |d|¡S)Nr/)rÀ)r r?rrrrr8 sz"JSONParser._do_modeled_error_parsec Cs^|j|}| ||¡}y | ¡}Wn tk rBd}t|ƒ‚YnX| |j|¡}|||<|S)Nz,First event was not of type initial-response)rqr]Zget_initial_responserr!rÀÚpayload) r r?rrÁZevent_stream_shapeZ event_streamr¶Ú error_msgr@rrrr¿s   zJSONParser._handle_event_streamcCs| |¡}| ||¡S)N)r§rT)r Zraw_bodyrZ parsed_jsonrrrrÀs zJSONParser._handle_json_bodyN) rrrr»r(r:r8r¿rÀrrrrr¾üs   r¾c@sTeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dS)ÚBaseRestParsercCs$i}| |¡|d<| |||¡|S)Nr2)Ú_populate_response_metadataÚ_add_modeled_parse)r r?rr£rrrr:%s  zBaseRestParser._do_parsecCs6|dkr |S|j}| ||||¡| ||||¡dS)N)rqr³r´)r r?rr£r¢rrrrÆ,s z!BaseRestParser._add_modeled_parsecCsi}| |||¡|S)N)rÆ)r r?rr£rrrr84sz&BaseRestParser._do_modeled_error_parsecCsJi}|d}d|kr"|d|d<n$d|krF|d|d<| dd¡|d<|S)Nr.zx-amzn-requestidr”zx-amz-request-idz x-amz-id-2rÚHostId)r<)r r?rCr.rrrrÅ9s z*BaseRestParser._populate_response_metadatac Cs¸d|jkr|jd}||}|j d¡r>| ||¡}|||<q´|jdkrp|d}t|tƒrf| |j¡}|||<q´| |d¡}|  ||¡||<n$| |d¡}|  ||¡} |  | ¡dS)NrÂr1)r¸r·r/) r;r<r]rPr=Úbytesr¬r_rµrTr) r r?rr¢r£Zpayload_member_nameZ body_shaper/r±r¹rrrr´Fs"          zBaseRestParser._parse_payloadc Cs¤|d}x–|D]Ž}||}|j d¡}|dkr2qq|dkrP| ||d¡||<q|dkrj| ||¡||<q|dkr|j d|¡} | |kr| ||| ¡||<qWdS)Nr.rnZ statusCoder0Úheaderr\)r;r<rTÚ_parse_header_map) r r?rr¢r£r.r\rWrnÚ header_namerrrr³^s"   z'BaseRestParser._parse_non_payload_attrscCsRi}|j dd¡ ¡}x6|D].}| ¡ |¡r|t|ƒd…}||||<qW|S)Nr\r)r;r<ÚlowerrEÚlen)r rr.r@ÚprefixrËr\rrrrÊrs z BaseRestParser._parse_header_mapcCs tdƒ‚dS)Nrµ)rM)r r°rrrrµsz"BaseRestParser._initial_body_parsecCs,|}t|ƒr(t |¡ |j¡}t |¡}|S)N)r r+r,r¬r_r­r®)r rr-r@Údecodedrrrr†s  zBaseRestParser._handle_stringN) rrrr:rÆr8rÅr´r³rÊrµrrrrrrÄ#s  rÄcs0eZdZeZdd„Z‡fdd„Zdd„Z‡ZS)ÚRestJSONParsercCs | |¡S)N)r§)r r°rrrrµ’sz"RestJSONParser._initial_body_parsecs"tt|ƒ ||¡}| ||¡|S)N)rarÐr9Ú_inject_error_code)r r?rr©)rNrrr9•s zRestJSONParser._do_error_parsecCsr| |d¡}d|dkrB|dd}| d¡d}||dd<n,d|ksRd|krn| d| dd ¡¡|dd<dS) Nr/zx-amzn-errortyper.rprrHrFrªr)rµrwr<)r r©r?r/rªrrrrÑšs  z!RestJSONParser._inject_error_code) rrrr»r(rµr9rÑr‘rr)rNrrÐŽs rÐcsDeZdZeZdd„Zdd„Zdd„Zdd„Ze ‡fd d „ƒZ ‡Z S) Ú RestXMLParsercCs|st d¡S| |¡S)Nr)rr½r†)r rƒrrrrµ­s z!RestXMLParser._initial_body_parsec CsN|drDy | |¡Stk rB}ztjdddWdd}~XYnX| |¡S)Nr/z2Exception caught when parsing error response body:T)Úexc_info)Ú_parse_error_from_bodyr!r3r4Ú_parse_error_from_http_status)r r?rr…rrrr9²s zRestXMLParser._do_error_parsecCsHt|dƒtjjj |dd¡dœ|d dd¡|d dd¡dœdœS) Nr0r)rFrGr.zx-amz-request-idz x-amz-id-2)r”rÇ)rHr2)rIrrJrKrLr<)r r?rrrrÕÌs   z+RestXMLParser._parse_error_from_http_statuscCs’|d}| |¡}| |¡}| |¡|jdkr\| |¡}| dd¡| dd¡||dœSd|krvd| d¡i|d<ddddœi}t||ƒ|S) Nr/rHr”rrÇ)rHr2r2)rGrF)r†rsr‡rmrÅr•r)r r?r–r„r@rCÚdefaultrrrrÔÙs         z$RestXMLParser._parse_error_from_bodycstt|ƒ ||¡}|S)N)rarÒr)r rr)rNrrrðszRestXMLParser._handle_string) rrrr¼r(rµr9rÕrÔr rr‘rr)rNrrÒ©s  rÒ)Zec2Úqueryr­z rest-jsonzrest-xml)(r^rbr+r­ÚloggingZbotocore.compatrrrZbotocore.eventstreamrrZbotocore.utilsrrr r Ú getLoggerrr3r#Úobjectr rr Ú Exceptionr!r"r`r’rŸr¡r²r»r¼r¾rÄrÐrÒrrrrrÚts@ *5%QN'kN