snakile
snakile

Reputation: 54521

Deterministically encode a dictionary as a url parameter list in Python

I'm using urllib.parse.urlencode to generate the parameters string of a url. The input to the function is a dictionary. The problem with calling urlencode on a dictionary is that the output is not deterministic. Namely, the order of the parameters in the resulting string is not consistent. The undeterministic behavior of urlencode makes it hard to test pieces of code that use it. Is there a deterministic equivalent of urlencode?

My current solution is to transform the dictionary into a list of tuples, sort it and then iterate the sorted list and generate the string. I'm asking whether such a function already exists.

Upvotes: 0

Views: 293

Answers (2)

Sym
Sym

Reputation: 537

If you have to use dicts then you can convert them to an OrderedDict before passing them to urlencode:

d = {'a': 1, 'b': 2}
urlencode(OrderedDict(sorted(d.items())))

This will convert the dict to the ordered two-element tuple falsetru mentions.

Upvotes: 0

falsetru
falsetru

Reputation: 369304

urllib.parse.urlencode accepts not only mapping (dictionary), but also a sequence of two-element tuple:

>>> import urllib.parse
>>> urllib.parse.urlencode([('a', 'b'), ('c', 'd')])
'a=b&c=d'
>>> urllib.parse.urlencode([('c', 'd'), ('a', 'b')])
'c=d&a=b'

If instead you just need an ordered mapping, use collections.OrderedDict instead.

Upvotes: 1

Related Questions