U ÞB1_˜¥ã@s~dZddlZddlZddlZddlZddlZddlmZm Z ddl m Z m Z ddl mZmZmZmZe e¡ZeZGdd„deƒZdd „Zd d „ZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZ Gdd„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Ú 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/2d/2jcwkxfx4hj39rq32sgz27wh9m_5lk/T/pip-target-h8a8k1vx/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ŽSr )ÚPROTOCOL_PARSERSr )r Z protocol_nameZ parser_clsrrrÚ create_parser–sz#ResponseParserFactory.create_parserN)Ú__name__Ú __module__Ú __qualname__rrrrrrrr †s r cCs tƒ |¡Sr )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)rr rrrÚ _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| ||¡|_dSr )ÚDEFAULT_TIMESTAMP_PARSERÚ_timestamp_parserÚ_default_blob_parserÚ _blob_parserÚ_event_stream_parserÚEVENT_STREAM_PARSER_CLS©r Ztimestamp_parserZ blob_parserrrrrÇs ÿzResponseParser.__init__cCs t |¡Sr )Ú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 rrrrr7 sz&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_parserPrSrrrr9.s ÿzResponseParser._do_error_parsecCstd|jjƒ‚dS)Nz%s._do_modeled_error_parserP)r r?rr@rrrr82s ÿz&ResponseParser._do_modeled_error_parsecCst|d|j|jƒ}|||ƒS)Nz _handle_%s)ÚgetattrÚ type_nameÚ_default_handle)r rÚnodeÚhandlerrrrÚ _parse_shape6s ÿzResponseParser._parse_shapecCs*g}|j}|D]}| | ||¡¡q|Sr )ÚmemberÚappendrY)r rrWr@Ú member_shapeÚitemrrrÚ _handle_list;s zResponseParser._handle_listcCs|Sr r©r rr-rrrrVDszResponseParser._default_handlecCs&|j}|d d¡}t|d|||ƒS)NÚcontextZoperation_namer/)r(r<r)r r?rÚparserÚnamerrrÚ_create_event_streamGsz#ResponseParser._create_event_stream)NN)rrrÚ__doc__ÚDEFAULT_ENCODINGr)rr&rAr7r5r6r:r9r8rYr^rVrcrrrrr#·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{.*})ÚsuperrfrÚreÚcompileÚ _namespace_rer*©rRrrrNs ÿzBaseXMLResponseParser.__init__c Cs®i}|j}|j}|j d¡pd}|j d¡p.d}|j d¡rLt|tƒsL|g}|D]X}|D]F} | | ¡} | |kr|| || ¡} qX| |kr’| || ¡} qXtd| ƒ‚qX| || <qP|S)NrbÚkeyr-Ú flattenedzUnknown tag: %s) rlr-r;r<r=ÚlistÚ _node_tagrYr") r rrWr@Ú key_shapeÚ value_shapeZkey_location_nameZvalue_location_nameZ keyval_nodeZ single_pairZtag_nameZkey_nameZval_namerrrÚ _handle_mapSs"  z!BaseXMLResponseParser._handle_mapcCs|j d|j¡S©Nr)rjÚsubÚtag)r rWrrrrohszBaseXMLResponseParser._node_tagcs.|j d¡rt|tƒs|g}tt|ƒ ||¡S)Nrm)r;r<r=rnrgrfr^)r rrWrkrrr^ksz"BaseXMLResponseParser._handle_listcCsði}|j}|j dd¡r"| |¡}| |¡}|D]º}||}d|jks0|j d¡rTq0| ||¡}| |¡} | dk r„| || ¡||<q0|j d¡r0i} |jd} |j  ¡D],\} } |j   |   d¡dd| ¡}| | |<q¨| | kr0| | ||<q0|S) NrBFÚlocationÚ eventheaderZ xmlAttributerbú:r) ÚmembersrCr<Ú_get_error_rootÚ_build_name_to_xml_noder;Ú_member_key_namerYÚattribÚitemsrjrtÚsplit)r rrWr@ryÚxml_dictÚ member_namer\Zxml_nameZ member_nodeZattribsZ location_namerlr-Znew_keyrrrÚ_handle_structureus<    ÿ  ÿ   ÿ z'BaseXMLResponseParser._handle_structurecCs2| |¡dkr.|D]}| |¡dkr|Sq|S)NZ ErrorResponserJ©ro)r Ú original_rootÚchildrrrrz’s  z%BaseXMLResponseParser._get_error_rootcCsL|jdkr0|j d¡r0|jj d¡}|dk r0|S|j d¡}|dk rH|S|S)Nrnrmrb)rUr;r<rZ)r rrZlist_member_serialized_nameZserialized_namerrrr|™sÿ z&BaseXMLResponseParser._member_key_namecCstt|tƒr| |d¡Si}|D]N}| |¡}||krft||tƒrT|| |¡qn|||g||<q |||<q |S)Nr)r=rnr{ror[)r Z parent_noder€r]rlrrrr{¨s   z-BaseXMLResponseParser._build_name_to_xml_nodec Csjz2tjjjtjj ¡|jd}| |¡| ¡}Wn2tk rd}zt d||fƒ‚W5d}~XYnX|S)N)ÚtargetÚencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed: %s) ÚxmlÚetreeÚ cElementTreeÚ XMLParserÚ TreeBuilderreÚfeedÚcloserr")r Ú xml_stringraÚrootÚerrrÚ_parse_xml_string_to_dom¿s þ  þÿz.BaseXMLResponseParser._parse_xml_string_to_domcCsB| ¡D]4\}}t|ƒr2| |¡}| |¡||<q|j||<q|Sr )r~rnr{Ú_replace_nodesr)r r@rlr-Zsub_dictrrrr“Ís   z$BaseXMLResponseParser._replace_nodescCs|dkr dSdSdS)NÚtrueTFr©r rrrrrÚ_handle_booleanÖsz%BaseXMLResponseParser._handle_booleancCst|ƒSr )Úfloatr•rrrÚ _handle_floatÝsz#BaseXMLResponseParser._handle_floatcCs | |¡Sr ©r%r•rrrÚ_handle_timestampász'BaseXMLResponseParser._handle_timestampcCst|ƒSr )Úintr•rrrÚ_handle_integeråsz%BaseXMLResponseParser._handle_integercCs|Sr rr•rrrÚ_handle_stringész$BaseXMLResponseParser._handle_stringcCs | |¡Sr ©r'r•rrrÚ _handle_blobísz"BaseXMLResponseParser._handle_blob)NN)rrrrrrror^r‚rzr|r{r’r“r!r–r˜ršrœrrŸZ_handle_characterZ_handle_doubleZ _handle_longÚ __classcell__rrrkrrfMs2        rfc@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’r{r“rÚpop)r r?rÚ xml_contentsrr@rrrr9øs   zQueryParser._do_error_parsecCs|j||ddS)NF©Úinject_metadata©Ú_parse_body_as_xmlrSrrrr8sz#QueryParser._do_modeled_error_parsecCs|j||ddS)NTr¦r¨rSrrrr: szQueryParser._do_parseTcCs^|d}| |¡}i}|dk rJ|}d|jkr>| |jd|¡}| ||¡}|rZ| ||¡|S)Nr/Z resultWrapper)r’r;Ú_find_result_wrapped_shaperYÚ_inject_response_metadata)r r?rr§r¥rr@Ústartrrrr©s  þ  zQueryParser._parse_body_as_xmlcCs| |¡}||Sr )r{)r Z element_nameZ xml_root_nodeÚmappingrrrrªs z&QueryParser._find_result_wrapped_shapecCsN| |¡}| d¡}|dk rJ| |¡}| ¡D]\}}|j||<q.||d<dS©Nr2)r{r<r~r)r rWÚ inject_intor­Ú child_nodeZ sub_mappingrlr-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)r{r<r)r rWr¯r­r°rrrr«-s  z(EC2QueryParser._inject_response_metadatacs0tt|ƒ ||¡}d|kr,d| d¡i|d<|S)NZ RequestIDr£r2)rgr±r9r¤)r r?rÚoriginalrkrrr93s ÿzEC2QueryParser._do_error_parsecCs@|D]6}| |¡dkr|D]}| |¡dkr|Sqq|S)Nr¢rJrƒ)r r„r…Z errors_childrrrrzGs zEC2QueryParser._get_error_root)rrrr«r9rzr rrrkrr±+s r±c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)ÚBaseJSONParserc Cs`|j}|dkrdSi}|D]@}||}|j d|¡}| |¡}|dk r| |||¡||<q|S)Nrb)ryr;r<rY) r rr-Ú member_shapesÚ final_parsedrr\Z json_nameZ raw_valuerrrr‚Rs þ z BaseJSONParser._handle_structurec CsFi}|j}|j}| ¡D](\}}| ||¡}| ||¡}|||<q|Sr )rlr-r~rY) r rr-r@rprqrlZ actual_keyZ actual_valuerrrrrds   zBaseJSONParser._handle_mapcCs | |¡Sr ržr_rrrrŸnszBaseJSONParser._handle_blobcCs | |¡Sr r™r_rrrršqsz BaseJSONParser._handle_timestampcCs˜| |d¡}dddœidœ}| d| dd¡¡|dd<| d¡}| d |oTt|ƒ¡}|dk r„d |krx| d d ¡d }||dd <| ||d ¡|S)Nr/r©rHrGrIÚmessagerHrJr0Z__typeú#érGr.)Ú_parse_body_as_jsonr<rKÚrsplitr«)r r?rr/ÚerrorZ response_codeÚcoderrrr9ts  ÿ   zBaseJSONParser._do_error_parsecCs d|kr|d| di¡d<dS)Núx-amzn-requestidr2r£)Ú setdefault)r r@r.rrrr«sÿz(BaseJSONParser._inject_response_metadatacCsF|siS| |j¡}zt |¡}|WStk r@d|iYSXdS)Nr·)ÚdecodereÚjsonÚloadsÚ ValueError)r Ú body_contentsr/Úoriginal_parsedrrrrº”s  z"BaseJSONParser._parse_body_as_jsonN) rrrr‚rrrŸršr9r«rºrrrrr³Ps 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<ryr:Ú_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/rJrHr·rrFz :error-codez:error-message)r<ryÚ_initial_body_parserY)r r?rZexception_typeZexception_shaperÅr/r¼rrrr9°s   þÿþÿz%BaseEventStreamParser._do_error_parsec Cs¦|j d¡r¢|D]l}||}|j d¡r|d}|jdkr@|}n.|jdkrX| |j¡}n| |¡} | || ¡}|||<dSq| |d¡} | || ¡} | | ¡dS)NÚeventZ eventpayloadr/ÚblobÚstring)r;r<rUrÀrerÉrYr) r r?rr´rµrbr\r/Z parsed_bodyZ raw_parserÅÚ body_parsedrrrrÈÅs        z$BaseEventStreamParser._parse_payloadc CsZ|d}|D]H}||}|j d¡r ||kr ||}|jdkrL| |d¡}|||<q dS)Nr.rwÚ timestampg@@)r;r<rUr%) r r?rr´rµr.rbr\r-rrrrÇÙs  z.BaseEventStreamParser._parse_non_payload_attrscCs tdƒ‚dS©NrÉ©rQ©r rÄrrrrÉçsz)BaseEventStreamParser._initial_body_parseN)rrrr:r9rÈrÇrÉrrrrrÆ¡s  rÆc@seZdZdd„ZdS)ÚEventStreamJSONParsercCs | |¡Sr ©rºrÑrrrrÉñsz)EventStreamJSONParser._initial_body_parseN©rrrrÉrrrrrÒïsrÒc@seZdZdd„ZdS)ÚEventStreamXMLParsercCs|stjj d¡S| |¡Srs©rˆr‰rŠÚElementr’©r rrrrrÉ÷sz(EventStreamXMLParser._initial_body_parseNrÔ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ÛrSrrrr8 sz"JSONParser._do_modeled_error_parsec Cs^|j|}| ||¡}z | ¡}Wn tk rBd}t|ƒ‚YnX| |j|¡}|||<|S)Nz,First event was not of type initial-response)ryrcZget_initial_responserr"rÛÚpayload) r r?rrÜZevent_stream_shapeZ event_streamrÊÚ error_msgr@rrrrÚs   zJSONParser._handle_event_streamcCs| |¡}| ||¡Sr )rºrY)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<| |||¡|Sr®)Ú_populate_response_metadataÚ_add_modeled_parse©r r?rrµrrrr:&s ÿzBaseRestParser._do_parsecCs6|dkr |S|j}| ||||¡| ||||¡dSr )ryrÇrÈ)r r?rrµr´rrrrá-sÿz!BaseRestParser._add_modeled_parsecCsi}| |||¡|Sr )rárârrrr85sz&BaseRestParser._do_modeled_error_parsecCsJi}|d}d|kr"|d|d<n$d|krF|d|d<| dd¡|d<|S)Nr.r¾r£úx-amz-request-idú x-amz-id-2rÚHostId)r<)r r?rCr.rrrrà:s 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<rcrUr=ÚbytesrÀrerÉrYr) r r?rr´rµZpayload_member_nameZ body_shaper/rÅrÍrrrrÈGs&         ÿ  zBaseRestParser._parse_payloadc Cs |d}|D]Ž}||}|j d¡}|dkr0q q |dkrN| ||d¡||<q |dkrh| ||¡||<q |dkr |j d|¡} | |kr | ||| ¡||<q dS)Nr.rvZ statusCoder0Úheaderrb)r;r<rYÚ_parse_header_map) r r?rr´rµr.rbr\rvÚ header_namerrrrÇ_s, ÿ ÿ ÿz'BaseRestParser._parse_non_payload_attrscCsNi}|j dd¡ ¡}|D].}| ¡ |¡r|t|ƒd…}||||<q|S)Nrbr)r;r<ÚlowerrEÚlen)r rr.r@Úprefixrérbrrrrèssz BaseRestParser._parse_header_mapcCs tdƒ‚dSrÏrÐrÑrrrrÉ€sz"BaseRestParser._initial_body_parsecCs,|}t|ƒr(t |¡ |j¡}t |¡}|Sr )rr+r,rÀrerÁ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 | |¡Sr rÓrÑrrrrÉ“sz"RestJSONParser._initial_body_parsecs"tt|ƒ ||¡}| ||¡|Sr )rgrîr9Ú_inject_error_code)r r?rr¼rkrrr9–s zRestJSONParser._do_error_parsecCsr| |d¡}d|dkrB|dd}| d¡d}||dd<n,d|ksRd|krn| d| dd ¡¡|dd<dS) Nr/zx-amzn-errortyper.rxrrJrGr½r)rÉrr<)r r¼r?r/r½rrrrï›s   ÿz!RestJSONParser._inject_error_code) rrrrÒr)rÉr9rïr rrrkrrîs rîcsDeZdZeZdd„Zdd„Zdd„Zdd„Ze ‡fd d „ƒZ ‡Z S) Ú RestXMLParsercCs|stjj d¡S| |¡SrsrÖrØrrrrÉ®sz!RestXMLParser._initial_body_parsec CsP|drFz | |¡WStk rD}ztjdddW5d}~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) Nr0rrFr.rãrä)r£rårI)rKrrLrMrNr<rOrrrróÍs  ÿþþúz+RestXMLParser._parse_error_from_http_statuscCs’|d}| |¡}| |¡}| |¡|jdkr\| |¡}| dd¡| dd¡||dœSd|krvd| d¡i|d<ddddœi}t||ƒ|S) Nr/rJr£rrårIr2r¶)r’r{r“ruràr¤r)r r?r¥rr@rCÚdefaultrrrròÚs         z$RestXMLParser._parse_error_from_bodycstt|ƒ ||¡}|Sr )rgrðrr•rkrrrñszRestXMLParser._handle_string) rrrrÕr)rÉr9róròr!rr rrrkrrðªs rð)Zec2ÚqueryrÁz rest-jsonzrest-xml))rdrhr+rÁZxml.etree.cElementTreerˆÚloggingZbotocore.compatrrZbotocore.eventstreamrrZbotocore.utilsrrrr Ú getLoggerrr3r$Úobjectr rr!Ú Exceptionr"r#rfr¡r±r³rÆrÒrÕrÙrßrîrðrrrrrÚ sDh *5%QN'kNû