python-requests: order get parameters
Solution 1
Currently requests doesn't allow to do this as you wish. This is of course shortcoming that will be fixed. However as params
parameter can take not only dictionary but bytes as well you should be able to do something in between:
from collections import OrderedDict
from urllib import urlencode
import requests
params = OrderedDict([('first', 1), ('second', 2), ('third', 3)])
requests.get('https://example.org/private_api', params=urlencode(params))
This doesn't work as I see due to bug in line 85 of models.py: self.params = dict(params or []
.
I raised this problem in issue Wrong handling of params given as bytes object
Solution 2
The requests lib now supports this out-of-the-box: To get ordered parameters you use a sequence of two-valued tuples instead. This eliminates the additional requirement of OrderedDict.
payload = (('key1', 'value1'), ('key2', 'value2'))
r = requests.get("http://httpbin.org/get", params=payload)
Demo:
>>> import requests
>>> requests.__version__
1.2.3
>>> payload = (('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'))
>>> r = requests.get("http://httpbin.org/get", params=payload)
>>> print r.json()['url']
http://httpbin.org/get?key1=value1&key2=value2&key3=value3
Solution 3
It used with version 2.2.0:
import requests
yourparams = {'s' : 'value1', 'f': 'value2'}
test = requests.get('https://example.org/private_api', params=yourparams)
print(test.url)
More details? Kindly check in here.
Solution 4
Line 85 of requests/models.py
(link) turns the params
object into a plain dict
, rather than the SortedDict
you passed in. I don't think you will be able to do what you want, unless you patch the library.
self.params = dict(params or [])
tback
Updated on July 09, 2022Comments
-
tback almost 2 years
I am implementing a client library for a private HTTP-API using python requests. The API(which I don't control) expects the parameters to be in a certain order, but python-requests doesn't honor a sorted dict as parameter.
This is what i tried:
import requests from django.utils.datastructures import SortedDict params = SortedDict() params['s'] = 'value1' params['f'] = 'value2' requests.get('https://example.org/private_api', params=params) #performs request as https://example.org/private_api?f=value1&s=value2
This is what I am trying to avoid:
requests.get('https://example.org?{0}'.format(urlencode(params)))
-
tback over 12 yearsConsidering the options at I think I'll have to go with what I was trying to avoid then. Thank you.
-
tback over 12 yearsThanks, I finally marked this as the solution as it provides the solution that is applicable in the foreseeable future.
-
Piotr Dobrogost over 12 years@TillBackhaus Already fixed.
-
Jian over 10 yearsWhat version does this work for? When I tried it in both
1.2.3
and2.0.0
,requests.get('http://example.org/private_api', params=urlencode(params)).request.body
returnedNone
-
Piotr Dobrogost almost 8 yearsThis does not preserve order of params which was requested by OP.