Python-запросы: порядок получения параметров - PullRequest
16 голосов
/ 10 января 2012

Я реализую клиентскую библиотеку для частного HTTP-API, используя Python запросов . API (который я не контролирую) ожидает, что параметры будут в определенном порядке, но Python-запросы не учитывают отсортированный dict как параметр.

Вот что я попробовал:

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 

Вот чего я стараюсь избегать:

requests.get('https://example.org?{0}'.format(urlencode(params)))

Ответы [ 5 ]

22 голосов
/ 28 августа 2013

Библиотека запросов теперь поддерживает это готовое решение: чтобы получить упорядоченные параметры, вместо этого вы используете последовательность двухзначных кортежей. Это устраняет дополнительное требование OrderedDict.

payload = (('key1', 'value1'), ('key2', 'value2'))
r = requests.get("http://httpbin.org/get", params=payload)

Демо-версия:

>>> 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
12 голосов
/ 10 января 2012

В настоящее время запросы не позволяют делать это, как вы хотите.Это, конечно, недостаток, который будет исправлен .Однако, поскольку параметр params может принимать не только словарь, но и байты, вы должны иметь возможность сделать что-то среднее между:

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))

Это не работает, как я вижу из-за ошибки в строке 85 моделей.py: self.params = dict(params or [].Я поднял эту проблему в вопросе Неправильная обработка параметров, переданных как объект байтов

1 голос
/ 10 января 2012

Строка 85 из requests/models.py ( ссылка ) превращает объект params в обычный dict, а не в SortedDict, который вы передали. Я не думаю, что вы сможете делать то, что вы хотите, если вы не исправляете библиотеку.

self.params = dict(params or [])
0 голосов
/ 02 февраля 2014

Используется с версией 2.2.0:

import requests
yourparams = {'s' : 'value1', 'f': 'value2'}

test = requests.get('https://example.org/private_api', params=yourparams)
print(test.url)

Подробнее?Пожалуйста, зарегистрируйтесь здесь .

0 голосов
/ 26 сентября 2013

Я обнаружил, что это работает в 1.2.3, а также 2.0.0

>>> import requests
>>> requests.__version__
'2.0.0'
>>> data = [('first', 1), ('second', 2), ('third', 3)]
>>> requests.get('http://example.org/private_api', data=data).request.body
'first=1&second=2&third=3'
...