݁[c@sdZddlZddlZddlZddlZddlZddlmZm Z ddl m Z ddl m Z mZmZmZejeZe ZdefdYZdZd Zd efd YZd efd YZdefdYZdefdYZdefdYZdefdYZdefdYZ defdYZ!de!efdYZ"de!efdYZ#defdYZ$d e$efd!YZ%d"e$efd#YZ&ied$6ed%6e d&6e%d'6e&d(6Z'dS()sResponse 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": , } } iN(tsixt XMLParseError(t EventStream(tparse_timestampt merge_dictstis_json_value_headertlowercase_dicttResponseParserFactorycBs#eZdZdZdZRS(cCs i|_dS(N(t _defaults(tself((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt__init__scKs|jj|dS(sOSet 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(Rtupdate(R tkwargs((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pytset_parser_defaultss cCst|}||jS(N(tPROTOCOL_PARSERSR(R t protocol_namet parser_cls((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt create_parsers (t__name__t __module__R R R(((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyRs  cCstj|S(N(RR(tprotocol((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyRscsfd}|S(NcsFt|dr0|j}|dkr6d}q6n|}|||S(Nttextt(thasattrRtNone(R tshapetnode_or_stringR(tfunc(sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt_get_text_contents    ((RR((Rsh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt _text_contents tResponseParserErrorcBseZRS((RR(((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyRstResponseParsercBszeZdZdZd Zd d dZdZdZdZ dZ dZ dZ d Z d Zd ZRS( soBase 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. sutf-8cCss|dkrt}n||_|dkr6|j}n||_d|_|jdk ro|j|||_ndS(N(RtDEFAULT_TIMESTAMP_PARSERt_timestamp_parsert_default_blob_parsert _blob_parsert_event_stream_parsertEVENT_STREAM_PARSER_CLS(R ttimestamp_parsert blob_parser((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR s       cCs tj|S(N(tbase64t b64decode(R tvalue((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR"scCstjd|dtjd|d|ddkrn|j|rY|j|}q|j||}n|j||}|r|jjdr|St|t r|jdi}|d|d <|d}t ||d <||dParse 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. sResponse headers: %stheaderssResponse body: %stbodyt status_codei-t eventstreamtResponseMetadatatHTTPStatusCodet HTTPHeaders( tLOGtdebugt_is_generic_error_responset_do_generic_error_parset_do_error_parset _do_parset serializationtgett isinstancetdictR(R tresponseRtparsedtresponse_metadataR+((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pytparses   cCsX|ddkrTd|ks,|ddkr0tS|dj}|jdpS| SdS(NR-iR,s(RtTruetstript startswith(R R<R,((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR4s cCsPtjdiit|dd6tjjjj|ddd6d6id6S(NslReceived a non protocol specific error response from the service, unable to populate error code and message.R-tCodeRtMessagetErrorR/(R2R3tstrRtmovest http_clientt responsesR9(R R<((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR5s  cCstd|jjdS(Ns %s._do_parse(tNotImplementedErrort __class__R(R R<R((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR7$scCstd|jjdS(Ns%s._do_error_parse(RJRKR(R R<R((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR6'scCs)t|d|j|j}|||S(Ns _handle_%s(tgetattrt type_namet_default_handle(R Rtnodethandler((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt _parse_shape+s cCs=g}|j}x'|D]}|j|j||qW|S(N(tmembertappendRQ(R RROR=t member_shapetitem((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyt _handle_list0s   cCs|S(N((R RR*((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyRN9sN(RRt__doc__tDEFAULT_ENCODINGRR%R R"R?R4R5R7R6RQRVRN(((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyRs   ,     tBaseXMLResponseParsercBseZdddZdZdZdZdZdZdZ dZ dZ e d Z e d Ze d Ze d Ze d Ze dZeZeZeZRS(cCs/tt|j||tjd|_dS(Ns{.*}(tsuperRYR tretcompilet _namespace_re(R R&R'((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR >sc Csi}|j}|j}|jjdp-d}|jjdpEd}|jjdrvt|t rv|g}nx|D]}xo|D]g} |j| } | |kr|j|| } q| |kr|j|| } qtd| qW| || scCs/tt|j||}|j|||S(N(RZRR6t_inject_error_code(R R<RR((sh/private/var/folders/71/gccz42bs2nl23mxwq3vp1qmhw5xjlw/T/pip-install-k836tR/botocore/botocore/parsers.pyR6AscCs|j|d}d|dkrU|dd}|jdd}||ddts@     "  .QBeM