B “äî\§ã@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 ú4/tmp/pip-build-uw_ogi45/botocore/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 Úkwargsr r rÚset_parser_defaultsŠs z)ResponseParserFactory.set_parser_defaultscCst|}|f|jŽS)N)ÚPROTOCOL_PARSERSr )r Z protocol_nameZ parser_clsr r rÚ create_parser–sz#ResponseParserFactory.create_parserN)Ú__name__Ú __module__Ú __qualname__rrrr r r rr †s r cCs tƒ |¡S)N)r r)Úprotocolr r rr›srcs‡fdd„}|S)Ncs.t|dƒr|j}|dkr"d}n|}ˆ|||ƒS)NÚtextÚ)Úhasattrr)r ÚshapeZnode_or_stringr)Úfuncr rÚ_get_text_content¥s  z(_text_content.._get_text_contentr )rrr )rrÚ _text_contentŸs rc@s eZdZdS)ÚResponseParserErrorN)rrrr r r rr ³sr c@sreZdZdZdZdZddd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dd„Z dd„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_parserr r rrÇs zResponseParser.__init__cCs t |¡S)N)Úbase64Ú b64decode)r Úvaluer r rr$Ósz#ResponseParser._default_blob_parsercCs²t d|d¡t d|d¡|ddkrP| |¡rB| |¡}q\| ||¡}n | ||¡}|rp|j d¡rp|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Ú_do_error_parseÚ _do_parseÚ serializationÚgetÚ isinstanceÚdictr )r ÚresponserÚparsedZresponse_metadatar-r r rÚparseÙs         zResponseParser.parsecCsD|ddkr@d|ks |ddkr$dS|d ¡}| d¡p>| SdS)Nr/iôr.Ts)ÚstripÚ startswith)r r<r.r r rr4s  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.r/r)ÚCodeÚMessage)ÚErrorr1)r2r3ÚstrrÚmovesÚ http_clientÚ responsesr9)r r<r r rr5s    z&ResponseParser._do_generic_error_parsecCstd|jjƒ‚dS)Nz %s._do_parse)ÚNotImplementedErrorÚ __class__r)r r<rr r rr7$szResponseParser._do_parsecCstd|jjƒ‚dS)Nz%s._do_error_parse)rHrIr)r r<rr r rr6'szResponseParser._do_error_parsecCst|d|j|jƒ}|||ƒS)Nz _handle_%s)ÚgetattrÚ type_nameÚ_default_handle)r rÚnodeÚhandlerr r rÚ _parse_shape+s zResponseParser._parse_shapecCs.g}|j}x|D]}| | ||¡¡qW|S)N)ÚmemberÚappendrO)r rrMr=Ú member_shapeÚitemr r rÚ _handle_list0s  zResponseParser._handle_listcCs|S)Nr )r rr,r r rrL9szResponseParser._default_handlecCs&|j}|d d¡}t|d|||ƒS)NÚcontextZoperation_namer.)r&r9r)r r<rÚparserÚnamer r rÚ_create_event_stream<sz#ResponseParser._create_event_stream)NN)rrrÚ__doc__ÚDEFAULT_ENCODINGr'rr$r>r4r5r7r6rOrTrLrXr r r rr!·s  ,  r!cs¶eZdZd ‡fdd„ Zdd„Zdd„Z‡fdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z e dd„ƒZ e dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZeZeZeZ‡ZS)!ÚBaseXMLResponseParserNcs"tt|ƒ ||¡t d¡|_dS)Nz{.*})Úsuperr[rÚreÚcompileÚ _namespace_re)r r(r))rIr rrCs 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)NrWÚkeyr,Ú flattenedzUnknown tag: %s) r`r,r8r9r:ÚlistÚ _node_tagrOr ) r rrMr=Ú key_shapeÚ value_shapeZkey_location_nameZvalue_location_nameZ keyval_nodeZ single_pairZtag_nameZkey_nameZval_namer r rÚ _handle_mapHs"    z!BaseXMLResponseParser._handle_mapcCs|j d|j¡S)Nr)r_ÚsubÚtag)r rMr r rrc]szBaseXMLResponseParser._node_tagcs.|j d¡rt|tƒs|g}tt|ƒ ||¡S)Nra)r8r9r:rbr\r[rT)r rrM)rIr rrT`sz"BaseXMLResponseParser._handle_listcCsài}|j}| |¡}xÆ|D]¾}||}d|jks|j d¡r>q| ||¡}| |¡} | dk rn| || ¡||<q|j d¡ri} |jd} x:|j ¡D],\} } |j  |   d¡dd| ¡}| | |<q”W| | kr| | ||<qW|S)NÚlocationÚ eventheaderZ xmlAttributerWú:r) ÚmembersÚ_build_name_to_xml_noder8r9Ú_member_key_namerOÚattribÚitemsr_rgÚsplit)r rrMr=rlÚxml_dictÚ member_namerRZxml_nameZ member_nodeZattribsZ location_namer`r,Znew_keyr r rÚ_handle_structurejs.         z'BaseXMLResponseParser._handle_structurecCsL|jdkr0|j d¡r0|jj d¡}|dk r0|S|j d¡}|dk rH|S|S)NrbrarW)rKr8r9rP)r rrsZlist_member_serialized_nameZserialized_namer r rrn…s z&BaseXMLResponseParser._member_key_namecCsxt|tƒr| |d¡Si}xV|D]N}| |¡}||krht||tƒrV|| |¡qp|||g||<q"|||<q"W|S)Nr)r:rbrmrcrQ)r Z parent_noderrrSr`r r rrm”s    z-BaseXMLResponseParser._build_name_to_xml_nodec Csjy2tjjjtjj ¡|jd}| |¡| ¡}Wn2tk rd}zt d||fƒ‚Wdd}~XYnX|S)N)ÚtargetÚencodingz7Unable to parse response (%s), invalid XML received: %s) ÚxmlÚetreeÚ cElementTreeÚ XMLParserÚ TreeBuilderrZÚfeedÚcloserr )r Ú xml_stringrVÚrootÚer r rÚ_parse_xml_string_to_dom«s    z.BaseXMLResponseParser._parse_xml_string_to_domcCsFx@| ¡D]4\}}t|ƒr4| |¡}| |¡||<q |j||<q W|S)N)rprbrmÚ_replace_nodesr)r r=r`r,Zsub_dictr r rr‚¸s  z$BaseXMLResponseParser._replace_nodescCs|dkr dSdSdS)NÚtrueTFr )r rrr r rÚ_handle_booleanÁsz%BaseXMLResponseParser._handle_booleancCst|ƒS)N)Úfloat)r rrr r rÚ _handle_floatÈsz#BaseXMLResponseParser._handle_floatcCs | |¡S)N)r#)r rrr r rÚ_handle_timestampÌsz'BaseXMLResponseParser._handle_timestampcCst|ƒS)N)Úint)r rrr r rÚ_handle_integerÐsz%BaseXMLResponseParser._handle_integercCs|S)Nr )r rrr r rÚ_handle_stringÔsz$BaseXMLResponseParser._handle_stringcCs | |¡S)N)r%)r rrr r rÚ _handle_blobØsz"BaseXMLResponseParser._handle_blob)NN)rrrrrfrcrTrtrnrmrr‚rr„r†r‡r‰rŠr‹Z_handle_characterZ_handle_doubleZ _handle_longÚ __classcell__r r )rIrr[Bs$        r[c@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) Ú QueryParsercCs\|d}| |¡}| |¡}| |¡d|kr>| | d¡¡d|krXd| d¡i|d<|S)Nr.ZErrorsÚ RequestIdr1)rrmr‚rÚpop)r r<rÚ xml_contentsrr=r r rr6ãs   zQueryParser._do_error_parsecCsZ|d}| |¡}i}|dk rJ|}d|jkr>| |jd|¡}| ||¡}| ||¡|S)Nr.Z resultWrapper)rr8Ú_find_result_wrapped_shaperOÚ_inject_response_metadata)r r<rrrr=Ústartr r rr7ós    zQueryParser._do_parsecCs| |¡}||S)N)rm)r Z element_nameZ xml_root_nodeÚmappingr r rr‘s z&QueryParser._find_result_wrapped_shapecCsR| |¡}| d¡}|dk rN| |¡}x| ¡D]\}}|j||<q0W||d<dS)Nr1)rmr9rpr)r rMÚ inject_intor”Ú child_nodeZ sub_mappingr`r,r r rr’s   z%QueryParser._inject_response_metadataN)rrrr6r7r‘r’r r r rrásrcs$eZdZdd„Z‡fdd„Z‡ZS)ÚEC2QueryParsercCs.| |¡}| d¡}|dk r*d|ji|d<dS)NZ requestIdrŽr1)rmr9r)r rMr•r”r–r r rr’s  z(EC2QueryParser._inject_response_metadatacs(tt|ƒ ||¡}d| d¡i|d<|S)NrŽZ RequestIDr1)r\r—r6r)r r<rÚoriginal)rIr rr6s zEC2QueryParser._do_error_parse)rrrr’r6rŒr r )rIrr—sr—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)NrW)rlr8r9rO) r rr,Ú member_shapesÚ final_parsedrsrRZ json_nameZ raw_valuer r rrt-s  z BaseJSONParser._handle_structurec CsJi}|j}|j}x4| ¡D](\}}| ||¡}| ||¡}|||<qW|S)N)r`r,rprO) r rr,r=rdrer`Z actual_keyZ actual_valuer r rrf?s   zBaseJSONParser._handle_mapcCs | |¡S)N)r%)r rr,r r rr‹IszBaseJSONParser._handle_blobcCs | |¡S)N)r#)r rr,r r rr‡Lsz BaseJSONParser._handle_timestampcCs˜| |d¡}dddœidœ}| d| dd¡¡|dd<| d¡}| d |oTt|ƒ¡}|dk r„d |krx| d d ¡d }||dd <| ||d ¡|S)Nr.r)rBrA)rCr1ÚmessagerBrCr/Z__typeú#érAr-)Ú_parse_body_as_jsonr9rDÚrsplitr’)r r<rr.ÚerrorZ response_codeÚcoder r rr6Os   zBaseJSONParser._do_error_parsecCs d|kr|d| di¡d<dS)Nzx-amzn-requestidr1rŽ)Ú setdefault)r r=r-r r rr’jsz(BaseJSONParser._inject_response_metadatacCs@|siS| |j¡}yt |¡}|Stk r:d|iSXdS)Nrœ)ÚdecoderZÚjsonÚloadsÚ ValueError)r Ú body_contentsr.Úoriginal_parsedr r rrŸos  z"BaseJSONParser._parse_body_as_jsonN) rrrrtrfr‹r‡r6r’rŸr r r rr™+s r™c@s4eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd S) ÚBaseEventStreamParsercCshi}|j d¡r@|d d¡}|j |¡}|rd| ||¡||<n$| |||j|¡| |||j|¡|S)Nr0r-z :event-type)r8r9rlr7Ú_parse_non_payload_attrsÚ_parse_payload)r r<rr›Z event_typeZ event_shaper r rr7~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.rCrBrœr)rArBz :error-codez:error-message)r9rlÚ_initial_body_parserO)r r<rZexception_typeZexception_shaper©r.r¡r r rr6‹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)r8r9rKr¤rZr­rOr) r r<rršr›rWrRr.Z parsed_bodyZ raw_parser©Ú body_parsedr r rr¬ s         z$BaseEventStreamParser._parse_payloadc Cs^|d}xP|D]H}||}|j d¡r||kr||}|jdkrN| |d¡}|||<qWdS)Nr-rjÚ timestampg@@)r8r9rKr#) r r<rršr›r-rWrRr,r r rr«´s   z.BaseEventStreamParser._parse_non_payload_attrscCs tdƒ‚dS)Nr­)rH)r r¨r r rr­Âsz)BaseEventStreamParser._initial_body_parseN)rrrr7r6r¬r«r­r r r rrª|s  rªc@seZdZdd„ZdS)ÚEventStreamJSONParsercCs | |¡S)N)rŸ)r r¨r r rr­Ìsz)EventStreamJSONParser._initial_body_parseN)rrrr­r r r rr³Êsr³c@seZdZdd„ZdS)ÚEventStreamXMLParsercCs|stjj d¡S| |¡S)Nr)rwrxryÚElementr)r r~r r rr­Òsz(EventStreamXMLParser._initial_body_parseN)rrrr­r r r rr´Ðsr´c@s(eZdZeZdd„Zdd„Zdd„ZdS)Ú JSONParsercCsJi}|dk r6|j}|r&| |||¡}n| |d|¡}| ||d¡|S)Nr.r-)Zevent_stream_nameÚ_handle_event_streamÚ_handle_json_bodyr’)r r<rr=Ú event_namer r rr7ÝszJSONParser._do_parsec Cs^|j|}| ||¡}y | ¡}Wn tk rBd}t|ƒ‚YnX| |j|¡}|||<|S)Nz,First event was not of type initial-response)rlrXZget_initial_responserr r¸Úpayload) r r<rr¹Zevent_stream_shapeZ event_streamr®Z error_msgr=r r rr·ès   zJSONParser._handle_event_streamcCs| |¡}| ||¡S)N)rŸrO)r Zraw_bodyrZ parsed_jsonr r rr¸ôs zJSONParser._handle_json_bodyN)rrrr³r'r7r·r¸r r r rr¶Øs  r¶c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)ÚBaseRestParsercCsHi}| |¡|d<|dkr|S|j}| ||||¡| ||||¡|S)Nr1)Ú_populate_response_metadatarlr«r¬)r r<rr›ršr r rr7þs zBaseRestParser._do_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)r9)r r<Úmetadatar-r r rr¼ 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ºr0)r°r¯r.) r8r9rXrKr:Úbytesr¤rZr­rOr) r r<rršr›Zpayload_member_nameZ body_shaper.r©r±r r rr¬s"          zBaseRestParser._parse_payloadc Cs¤|d}x–|D]Ž}||}|j d¡}|dkr2qq|dkrP| ||d¡||<q|dkrj| ||¡||<q|dkr|j d|¡} | |kr| ||| ¡||<qWdS)Nr-riZ statusCoder/ÚheaderrW)r8r9rOÚ_parse_header_map) r r<rršr›r-rWrRriÚ header_namer r rr«/s"   z'BaseRestParser._parse_non_payload_attrscCsRi}|j dd¡ ¡}x6|D].}| ¡ |¡r|t|ƒd…}||||<qW|S)NrWr)r8r9Úlowerr@Úlen)r rr-r=ÚprefixrÂrWr r rrÁCs z BaseRestParser._parse_header_mapcCs tdƒ‚dS)Nr­)rH)r r¨r r rr­Psz"BaseRestParser._initial_body_parsecCs,|}t|ƒr(t |¡ |j¡}t |¡}|S)N)rr*r+r¤rZr¥r¦)r rr,r=Údecodedr r rrŠWs  zBaseRestParser._handle_stringN) rrrr7r¼r¬r«rÁr­rŠr r r rr»üs   r»cs0eZdZeZdd„Z‡fdd„Zdd„Z‡ZS)ÚRestJSONParsercCs | |¡S)N)rŸ)r r¨r r rr­csz"RestJSONParser._initial_body_parsecs"tt|ƒ ||¡}| ||¡|S)N)r\rÇr6Ú_inject_error_code)r r<rr¡)rIr rr6fs zRestJSONParser._do_error_parsecCsr| |d¡}d|dkrB|dd}| d¡d}||dd<n,d|ksRd|krn| d| dd ¡¡|dd<dS) Nr.zx-amzn-errortyper-rkrrCrAr¢r)r­rqr9)r r¡r<r.r¢r r rrÈks  z!RestJSONParser._inject_error_code) rrrr³r'r­r6rÈrŒr r )rIrrÇ_s rÇcsDeZdZeZdd„Zdd„Zdd„Zdd„Ze ‡fd d „ƒZ ‡Z S) Ú RestXMLParsercCs|stjj d¡S| |¡S)Nr)rwrxryrµr)r r~r r rr­~sz!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 r2r3Ú_parse_error_from_http_status)r r<rr€r r rr6ƒs zRestXMLParser._do_error_parsecCsHt|dƒtjjj |dd¡dœ|d dd¡|d dd¡dœdœS) Nr/r)rArBr-zx-amz-request-idz x-amz-id-2)rŽr½)rCr1)rDrrErFrGr9)r r<r r rrÌs   z+RestXMLParser._parse_error_from_http_statuscCs’|d}| |¡}| |¡}| |¡|jdkr\| |¡}| dd¡| dd¡||dœSd|krvd| d¡i|d<ddddœi}t||ƒ|S) Nr.rCrŽrr½)rCr1r1)rBrA)rrmr‚rhr¼rr)r r<rrr=r¾Údefaultr r rr˪s         z$RestXMLParser._parse_error_from_bodycstt|ƒ ||¡}|S)N)r\rÉrŠ)r rr)rIr rrŠÁszRestXMLParser._handle_string) rrrr´r'r­r6rÌrËrrŠrŒr r )rIrrÉzs  rÉ)Zec2Úqueryr¥z rest-jsonzrest-xml))rYr]r*r¥Úxml.etree.cElementTreerwÚloggingZbotocore.compatrrZbotocore.eventstreamrrZbotocore.utilsrrrr Ú getLoggerrr2r"Úobjectr rrÚ Exceptionr r!r[rr—r™rªr³r´r¶r»rÇrÉrr r r rÚtsB   .QN$cN