I am using an API that doesn't accept JSON in the requests' bodies. It uses x-www-form-urlencoded
.
Thus, if I have to send this dict
:
{
'a': 1,
'b': 2,
'c': {
'k': 3,
'v': 4,
'l': {
'p': 5,
'q': 6,
},
},
}
It have to be encoded like this:
a=1
b=2
c[k]=3
c[v]=4
c[l][p]=5
c[l][q]=6
However, urllib.parse.urlencode
won't parse the dict
this way. Instead it's going to encode c
content literally and put within it (c={encodeddict}
).
I tried to implement some encoder like this by myself, but I couldn't get to deal with multiple nested dicts
. I only managed to encode 1-level dicts
(like c[k]=3
), but not recursively to the last level (c[l][p]=5
, for example).
What is the best way to achieve this kind of encoding in Python 3?
Using recursion:
pass your dict to dict_to_urlencoded(), and it'll return encoded format string based on your description. (unsorted)
def dict_to_urlencoded(d):
return kv_translation(d, "", "")
def kv_translation(d, line, final_str):
for key, value in d.items():
key_str = key if not line else "[{}]".format(key)
if type(value) is dict:
final_str = kv_translation(d[key], line + key_str, final_str)
elif type(value) is list:
key_str += '[]'
elif type(value) is not str:
value = str(value)
else:
final_str = "{}{}{}={}\n".format(final_str, line, key_str, urlencode(value))
return final_str