Search code examples
pythonxmltornado

How does tornado post xml data when using AsyncHTTPClient?


I use Tornado 4.2 and I need to send xml data with POST request. If I use requests library it's working as expected:

 r = requests.post(url, headers=headers, data=send_xml, verify=False)
 prepay_result_dic = cls.trans_xml_to_dict(r.content)

How can I achieve the same functionality with tornado.httpclient.AsyncHTTPClient? I've tried:

@tornado.gen.coroutine
def post_async_url(url, payload={}, headers={}):
    '''
    post url,to replace the requests lib...
    :param url: "http://www.google.com/"
    :param payload: {'userId': user_id}
    :return: response.body
    '''
    import urllib
    http_client = tornado.httpclient.AsyncHTTPClient()
    payload = urllib.urlencode(payload)
    response = yield tornado.gen.Task(http_client.fetch, url, method="POST", headers=headers, body=payload, validate_cert=False)
    raise tornado.gen.Return(response.body)

But the above code raises an error:

TypeError: not a valid non-string sequence or mapping object

Solution

  • This error isn't coming from Tornado, it's coming from urllib.urlencode, and it can happen when you try to call that function on a string instead of a dict. The comments indicate that payload is supposed to be a dict, but since your question is asking about XML, is payload a string instead? If so, you can pass it directly as the body of the request, without url-encoding it.