ftg
ftg

Reputation: 11

Python POST with urlencoded multidimensional dictionary

I have many functions that successfully POST a urlencoded body using python. However, I have a body that is a multidimensional dictionary. Using this dictionary, I only get a 400 (bad request). bodytmp (below) is an example of the body that works using Fiddler. (The actual url and body can not be supplied.) I have also included a recursive urlencode function that I found here and am using now but with no success.

Does anyone have experience with this type of POST request with a multidimensional dictionary for the urlencoded body?

Thank you. ( I have abbreviated the code to make it more readable, but this is the gist. )

from httplib2 import Http import httplib import urllib

def postAgentRegister():

h = Http(disable_ssl_certificate_validation=True)
headers={'Content-Type':'application/x-www-form-urlencoded'}

bodytmp={"Username": "username",
        "Password": "password",
        "AccountId": "accountid",
        "PublicKey": {
        "Value1a": "32ab45cd",
        "value1b": "10001"
                     },
        "snId": "SN1",
        "IpAddresses": {
        "Value2a": ["50.156.54.45"],
        "Value2b": "null"
                   }
        }

body=recursive_urlencode(bodytmp)

try:
    response,content=h.request('https://server/endpoint','POST',headers=headers,body=body)
    conn = httplib.HTTPConnection(testserver)
    conn.request('POST', endpoint, body, headers)
    r1 = conn.getresponse()
    status = r1.status
    reason = r1.reason

except httplib.HTTPException, e:
    status= e.code

print 'status is: ', status

def recursive_urlencode(d): def recursion(d, base=None): pairs = []

    for key, value in d.items():
        if hasattr(value, 'values'):
            pairs += recursion(value, key)
        else:
            new_pair = None
            if base:
                new_pair = "%s[%s]=%s" % (base, urllib.quote(unicode(key)), urllib.quote(unicode(value)))
            else:
                new_pair = "%s=%s" % (urllib.quote(unicode(key)), urllib.quote(unicode(value)))
            pairs.append(new_pair)
    return pairs

return '&'.join(recursion(d))

Upvotes: 1

Views: 1774

Answers (1)

Charles Ma
Charles Ma

Reputation: 49131

Might I suggest that you serialize your body to JSON and de-serialize when your server receives it? This way you just have to do a url string encode rather than using your own recursive url encode.

Upvotes: 1

Related Questions