Pregunta

Estoy implementando una biblioteca de clientes para un HTTP-API privado utilizando Solicitudes de Python. La API (que no controlo) espera que los parámetros estén en un cierto orden, pero Python-Requests no honra a un dict ordenado como parámetro.

Esto es lo que probé:

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 

Esto es lo que estoy tratando de evitar:

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

Solución

Actualmente las solicitudes no permiten hacer esto como desee. Esta es, por supuesto, deficiente que será fijado. sin embargo, como params El parámetro puede tomar no solo el diccionario sino también bytes, también debería poder hacer algo intermedio:

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

Esto no funciona como veo debido al error en la línea 85 de modelos.py: self.params = dict(params or []. Planteé este problema en cuestión Manejo incorrecto de parámetros dados como objeto bytes

Otros consejos

Las solicitudes LIB ahora admiten esta lista de usar: para obtener parámetros ordenados, utiliza una secuencia de tuplas de dos valores. Esto elimina el requisito adicional de orden de orden.

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

Manifestación:

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

Línea 85 de requests/models.py (Enlace) gira el params Objetar en una llanura dict, en lugar del SortedDict Pasaste. No creo que puedas hacer lo que quieres, a menos que parche la biblioteca.

self.params = dict(params or [])

Encontré que esto funciona en 1.2.3 tanto como 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'

Se usa con la versión 2.2.0:

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

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

¿Más detalles? Vuelva a verificar amablemente aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top