U a=@szdZddlZddlZddlZddlZddlmZmZmZddl m Z m Z ddl m Z mZmZmZeeZe ZGdddeZdd Zd d ZGd d d eZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZ Gddde eZ!Gddde eZ"GdddeZ#Gd d!d!eZ$Gd"d#d#e$eZ%Gd$d%d%e$eZ&eee#e%e&d&Z'dS)'aResponse 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)sixETree XMLParseError) EventStreamNoInitialResponseError)parse_timestamp merge_dictsis_json_value_headerlowercase_dictc@s$eZdZddZddZddZdS)ResponseParserFactorycCs i|_dSN) _defaults)selfr/Users/jalaguru/Documents/Proserv/artifacts/aws_dms_cdk_automation/aws-dms-cdk-automation/venv/lib/python3.8/site-packages/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 timestamp string * blob_parser - A callable that can parse a blob type N)r update)rkwargsrrrset_parser_defaultss z)ResponseParserFactory.set_parser_defaultscCst|}|f|jSr )PROTOCOL_PARSERSr )rZ protocol_nameZ parser_clsrrr create_parsersz#ResponseParserFactory.create_parserN)__name__ __module__ __qualname__rrrrrrrr s r cCs t|Sr )r r)protocolrrrrsrcsfdd}|S)Ncs.t|dr|j}|dkr"d}n|}|||S)Ntext)hasattrr)rshapeZnode_or_stringrfuncrr_get_text_contents  z(_text_content.._get_text_contentr)r r!rrr _text_contents r"c@s eZdZdS)ResponseParserErrorN)rrrrrrrr#sr#c@seZdZdZdZdZdddZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZddZddZddZddZdS)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_parserEVENT_STREAM_PARSER_CLSrZtimestamp_parserZ blob_parserrrrrs zResponseParser.__init__cCs t|Sr )base64 b64decode)rvaluerrrr'sz#ResponseParser._default_blob_parsercCstd|dtd|d|ddkrj||rB||}qv||r\|||}|S|||}n |||}|r|j dr|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: %sheaderszResponse body: %sbody status_codei- eventstreamResponseMetadataZHTTPStatusCodeZ HTTPHeaders) LOGdebug_is_generic_error_response_do_generic_error_parse_is_modeled_error_shape_do_modeled_error_parse_do_error_parse _do_parse serializationget isinstancedictr )rresponserparsedZresponse_metadatar/rrrparses&          zResponseParser.parsecCs|dk o|jddS)N exceptionF)metadatar=)rrrrrr8sz&ResponseParser._is_modeled_error_shapecCsD|ddkr@d|ks |ddkr$dS|d}|dp>| SdS)Nr1ir0Ts)strip startswith)rr@r0rrrr6 s  z)ResponseParser._is_generic_error_responsecCs4tdt|dtjjj|dddidS)NzlReceived a non protocol specific error response from the service, unable to populate error code and message.r1rCodeMessageErrorr3)r4r5strrmoves http_client responsesr=rr@rrrr7s   z&ResponseParser._do_generic_error_parsecCstd|jjdS)Nz %s._do_parseNotImplementedError __class__rrr@rrrrr;*szResponseParser._do_parsecCstd|jjdS)Nz%s._do_error_parserQrTrrrr:-s zResponseParser._do_error_parsecCstd|jjdS)Nz%s._do_modeled_error_parserQ)rr@rrArrrr91s z&ResponseParser._do_modeled_error_parsecCst|d|j|j}|||S)Nz _handle_%s)getattr type_name_default_handle)rrnodehandlerrrr _parse_shape5s zResponseParser._parse_shapecCs*g}|j}|D]}||||q|Sr )memberappendrZ)rrrXrA member_shapeitemrrr _handle_list:s zResponseParser._handle_listcCs|Sr rrrr.rrrrWCszResponseParser._default_handlecCs&|j}|dd}t|d|||S)NcontextZoperation_namer0)r)r=r)rr@rparsernamerrr_create_event_streamFsz#ResponseParser._create_event_stream)NN)rrr__doc__DEFAULT_ENCODINGr*rr'rBr8r6r7r;r:r9rZr_rWrdrrrrr$s   0  r$cseZdZd"fdd ZddZddZfdd Zd d Zd d ZddZ ddZ ddZ ddZ e ddZe ddZe ddZe ddZe ddZe d d!ZeZeZeZZS)#BaseXMLResponseParserNcs"tt|||td|_dS)Nz{.*})superrgrrecompile _namespace_rer+rSrrrMs zBaseXMLResponseParser.__init__c Csi}|j}|j}|jdpd}|jdp.d}|jdrLt|tsL|g}|D]X}|D]F} || } | |kr|||| } qX| |kr||| } qXtd| qX| || <qP|S)Nrckeyr. flattenedzUnknown tag: %s) rmr.r<r=r>list _node_tagrZr#) rrrXrA key_shape value_shapeZkey_location_nameZvalue_location_nameZ keyval_nodeZ single_pairZtag_nameZkey_nameZval_namerrr _handle_mapRs"  z!BaseXMLResponseParser._handle_mapcCs|jd|jSNr)rksubtag)rrXrrrrpgszBaseXMLResponseParser._node_tagcs.|jdrt|ts|g}tt|||S)Nrn)r<r=r>rorhrgr_)rrrXrlrrr_jsz"BaseXMLResponseParser._handle_listcCsi}|j}|jddr"||}||}|D]}||}d|jks0|jdrTq0|||}||} | dk r||| ||<q0|jdr0i} |jd} |j D],\} } |j | ddd| }| | |<q| | kr0| | ||<q0|S) NrCFlocation eventheaderZ xmlAttributerc:r) membersrDr=_get_error_root_build_name_to_xml_noder<_member_key_namerZattribitemsrkrusplit)rrrXrArzxml_dict member_namer]Zxml_nameZ member_nodeZattribsZ location_namermr.Znew_keyrrr_handle_structurets<          z'BaseXMLResponseParser._handle_structurecCs2||dkr.|D]}||dkr|Sq|S)NZ ErrorResponserKrp)r original_rootchildrrrr{s  z%BaseXMLResponseParser._get_error_rootcCsL|jdkr0|jdr0|jjd}|dk r0|S|jd}|dk rH|S|S)Nrornrc)rVr<r=r[)rrrZlist_member_serialized_nameZserialized_namerrrr}s z&BaseXMLResponseParser._member_key_namecCstt|tr||dSi}|D]N}||}||krft||trT|||qn|||g||<q |||<q |S)Nr)r>ror|rpr\)rZ parent_noderr^rmrrrr|s   z-BaseXMLResponseParser._build_name_to_xml_nodec Csbz*tjt|jd}|||}Wn2tk r\}ztd||fW5d}~XYnX|S)N)targetencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed: %s)r XMLParser TreeBuilderrffeedcloserr#)r xml_stringrbrooterrr_parse_xml_string_to_doms  z.BaseXMLResponseParser._parse_xml_string_to_domcCsB|D]4\}}t|r2||}||||<q|j||<q|Sr )rror|_replace_nodesr)rrArmr.Zsub_dictrrrrs   z$BaseXMLResponseParser._replace_nodescCs|dkr dSdSdS)NtrueTFrrrrrrr_handle_booleansz%BaseXMLResponseParser._handle_booleancCst|Sr )floatrrrr _handle_floatsz#BaseXMLResponseParser._handle_floatcCs ||Sr r&rrrr_handle_timestampsz'BaseXMLResponseParser._handle_timestampcCst|Sr )intrrrr_handle_integersz%BaseXMLResponseParser._handle_integercCs|Sr rrrrr_handle_stringsz$BaseXMLResponseParser._handle_stringcCs ||Sr r(rrrr _handle_blobsz"BaseXMLResponseParser._handle_blob)NN)rrrrrsrpr_rr{r}r|rrr"rrrrrrZ_handle_characterZ_handle_doubleZ _handle_long __classcell__rrrlrrgLs2        rgc@s>eZdZddZddZddZddd Zd d Zd d ZdS) QueryParsercCs\|d}||}||}||d|kr>||dd|krXd|di|d<|S)Nr0Errors RequestIdr3)rr|rrpop)rr@r xml_contentsrrArrrr:s   zQueryParser._do_error_parsecCs|j||ddS)NFinject_metadata_parse_body_as_xmlrTrrrr9sz#QueryParser._do_modeled_error_parsecCs|j||ddS)NTrrrTrrrr; szQueryParser._do_parseTcCs^|d}||}i}|dk rJ|}d|jkr>||jd|}|||}|rZ||||S)Nr0Z resultWrapper)rr<_find_result_wrapped_shaperZ_inject_response_metadata)rr@rrrrrAstartrrrr s    zQueryParser._parse_body_as_xmlcCs||}||Sr )r|)rZ element_nameZ xml_root_nodemappingrrrrs z&QueryParser._find_result_wrapped_shapecCsN||}|d}|dk rJ||}|D]\}}|j||<q.||d<dSNr3)r|r=rr)rrX inject_intor child_nodeZ sub_mappingrmr.rrrr s    z%QueryParser._inject_response_metadataN)T) rrrr:r9r;rrrrrrrrs  rcs,eZdZddZfddZddZZS)EC2QueryParsercCs.||}|d}|dk r*d|ji|d<dS)NZ requestIdrr3)r|r=r)rrXrrrrrrr,s  z(EC2QueryParser._inject_response_metadatacs0tt|||}d|kr,d|di|d<|S)NZ RequestIDrr3)rhrr:r)rr@roriginalrlrrr:2s zEC2QueryParser._do_error_parsecCs@|D]6}||dkr|D]}||dkr|Sqq|S)NrrKr)rrrZ errors_childrrrr{Fs zEC2QueryParser._get_error_root)rrrrr:r{rrrrlrr*s rc@sDeZdZddZddZddZddZd d Zd d Zd dZ dS)BaseJSONParserc Cs`|j}|dkrdSi}|D]@}||}|jd|}||}|dk r||||||<q|S)Nrc)rzr<r=rZ) rrr. member_shapes final_parsedrr]Z json_nameZ raw_valuerrrrQs  z BaseJSONParser._handle_structurec CsFi}|j}|j}|D](\}}|||}|||}|||<q|Sr )rmr.rrZ) rrr.rArqrrrmZ actual_keyZ actual_valuerrrrscs   zBaseJSONParser._handle_mapcCs ||Sr rr`rrrrmszBaseJSONParser._handle_blobcCs ||Sr rr`rrrrpsz BaseJSONParser._handle_timestampcCs||d}dddid}|d|dd|dd<|d}|d |oTt|}|dk rd |krx|d d d }||dd <|||d |S)Nr0rrIrHrJmessagerIrKr1Z__type#rHr/)_parse_body_as_jsonr=rLrsplitr)rr@rr0errorZ response_codecoderrrr:ss    zBaseJSONParser._do_error_parsecCs d|kr|d|did<dS)Nx-amzn-requestidr3r) setdefault)rrAr/rrrrsz(BaseJSONParser._inject_response_metadatacCsF|siS||j}zt|}|WStk r@d|iYSXdS)Nr)decoderfjsonloads ValueError)r body_contentsr0original_parsedrrrrs  z"BaseJSONParser._parse_body_as_jsonN) rrrrrsrrr:rrrrrrrOs rc@s4eZdZddZddZddZddZd d Zd S) BaseEventStreamParsercCshi}|jdr@|dd}|j|}|rd|||||<n$||||j|||||j||S)Nr2r/z :event-type)r<r=rzr;_parse_non_payload_attrs_parse_payload)rr@rrZ event_typeZ event_shaperrrr;s  zBaseEventStreamParser._do_parsec Cs|dd}|j|}|dk r\||d}|||}d||d|dddi}n&d|dd d|dd ddi}|S) Nr/z:exception-typer0rKrIrrrGz :error-codez:error-message)r=rz_initial_body_parserZ)rr@rZexception_typeZexception_shaperr0rrrrr:s   z%BaseEventStreamParser._do_error_parsec Cs|jdr|D]l}||}|jdr|d}|jdkr@|}n.|jdkrX||j}n||} ||| }|||<dSq||d} ||| } || dS)NeventZ eventpayloadr0blobstring)r<r=rVrrfrrZr) rr@rrrrcr]r0Z parsed_bodyZ raw_parser body_parsedrrrrs        z$BaseEventStreamParser._parse_payloadc CsZ|d}|D]H}||}|jdr ||kr ||}|jdkrL||d}|||<q dS)Nr/rx timestampg@@)r<r=rVr&) rr@rrrr/rcr]r.rrrrs  z.BaseEventStreamParser._parse_non_payload_attrscCs tddSNrrRrrrrrrsz)BaseEventStreamParser._initial_body_parseN)rrrr;r:rrrrrrrrs  rc@seZdZddZdS)EventStreamJSONParsercCs ||Sr rrrrrrsz)EventStreamJSONParser._initial_body_parseNrrrrrrrrrsrc@seZdZddZdS)EventStreamXMLParsercCs|stdS||SrtrElementrrrrrrrs z(EventStreamXMLParser._initial_body_parseNrrrrrrsrc@s0eZdZeZddZddZddZddZd S) JSONParsercCsJi}|dk r6|j}|r&||||}n||d|}|||d|S)Nr0r/)Zevent_stream_name_handle_event_stream_handle_json_bodyr)rr@rrA event_namerrrr;szJSONParser._do_parsecCs||d|S)Nr0)rrTrrrr9 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)rzrdZget_initial_responserr#rpayload) rr@rrZevent_stream_shapeZ event_streamr error_msgrArrrrs   zJSONParser._handle_event_streamcCs||}|||Sr )rrZ)rZraw_bodyrZ parsed_jsonrrrrs zJSONParser._handle_json_bodyN) rrrrr*r;r9rrrrrrrs   rc@sTeZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ dS)BaseRestParsercCs$i}|||d<|||||Sr)_populate_response_metadata_add_modeled_parserr@rrrrrr;%s zBaseRestParser._do_parsecCs6|dkr |S|j}||||||||||dSr )rzrr)rr@rrrrrrr,sz!BaseRestParser._add_modeled_parsecCsi}|||||Sr )rrrrrr94sz&BaseRestParser._do_modeled_error_parsecCsJi}|d}d|kr"|d|d<n$d|krF|d|d<|dd|d<|S)Nr/rrx-amz-request-id x-amz-id-2rHostId)r=)rr@rDr/rrrr9s z*BaseRestParser._populate_response_metadatac Csd|jkr|jd}||}|jdr>|||}|||<q|jdkrp|d}t|trf||j}|||<q||d}| ||||<n$||d}| ||} | | dS)Nrr2)rrr0) r<r=rdrVr>bytesrrfrrZr) rr@rrrZpayload_member_nameZ body_shaper0rrrrrrFs&           zBaseRestParser._parse_payloadc Cs|d}|D]}||}|jd}|dkr0q q |dkrN|||d||<q |dkrh|||||<q |dkr |jd|} | |kr |||| ||<q dS)Nr/rwZ statusCoder1headerrc)r<r=rZ_parse_header_map) rr@rrrr/rcr]rw header_namerrrr^s,   z'BaseRestParser._parse_non_payload_attrscCsNi}|jdd}|D].}||r|t|d}||||<q|S)Nrcr)r<r=lowerrFlen)rrr/rAprefixrrcrrrrrsz BaseRestParser._parse_header_mapcCs tddSrrrrrrrsz"BaseRestParser._initial_body_parsecCs,|}t|r(t||j}t|}|Sr )r r,r-rrfrr)rrr.rAdecodedrrrrs  zBaseRestParser._handle_stringN) rrrr;rr9rrrrrrrrrrr#s  rcs0eZdZeZddZfddZddZZS)RestJSONParsercCs ||Sr rrrrrrsz"RestJSONParser._initial_body_parsecs"tt|||}||||Sr )rhrr:_inject_error_code)rr@rrrlrrr:s zRestJSONParser._do_error_parsecCsr||d}d|dkrB|dd}|dd}||dd<n,d|ksRd|krn|d|dd |dd<dS) Nr0zx-amzn-errortyper/ryrrKrHrr)rrr=)rrr@r0rrrrrs   z!RestJSONParser._inject_error_code) rrrrr*rr:rrrrrlrrs rcsDeZdZeZddZddZddZddZe fd d Z Z S) RestXMLParsercCs|stdS||Srtrrrrrrs z!RestXMLParser._initial_body_parsec CsP|drFz ||WStk rD}ztjdddW5d}~XYnX||S)Nr0z2Exception caught when parsing error response body:T)exc_info)_parse_error_from_bodyr#r4r5_parse_error_from_http_status)rr@rrrrrr:s zRestXMLParser._do_error_parsecCsHt|dtjjj|ddd|ddd|dddddS) Nr1rrGr/rr)rrrJ)rLrrMrNrOr=rPrrrrs  z+RestXMLParser._parse_error_from_http_statuscCs|d}||}||}|||jdkr\||}|dd|dd||dSd|krvd|di|d<ddddi}t|||S) Nr0rKrrrrJr3r)rr|rrvrrr)rr@rrrArDdefaultrrrrs         z$RestXMLParser._parse_error_from_bodycstt|||}|Sr )rhrrrrlrrrszRestXMLParser._handle_string) rrrrr*rr:rrr"rrrrrlrrs r)Zec2queryrz rest-jsonzrest-xml)(rerir,rloggingZbotocore.compatrrrZbotocore.eventstreamrrZbotocore.utilsrrr r getLoggerrr4r%objectr rr" Exceptionr#r$rgrrrrrrrrrrrrrrr sBh *5%QN'kN