Domanda

I sono l'attuazione di una libreria client per un HTTP-API privata utilizzando richieste . L'API (che io non controllo) si aspetta che i parametri siano in un certo ordine, ma python-richieste non onora un dict ordinato come parametro.

Questo è quello che ho provato:

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 

Questo è quello che sto cercando di evitare:

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

Soluzione

Al momento le richieste non permette di fare questo come si desidera. Questo è, naturalmente, lacuna che verrà fissato . Tuttavia, come parametro di params può prendere dizionario non solo, ma byte, così si dovrebbe essere in grado di fare una via di mezzo:

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

Questo non funziona come la vedo a causa di bug in linea 85 del models.py: self.params = dict(params or []. Ho sollevato questo problema in questione manipolazione errata di params dati come byte oggetto

Altri suggerimenti

Le richieste lib ora supporta questo out-of-the-box: Per ottenere i parametri ordinati si utilizza una sequenza di due valori tuple invece. Questo elimina il requisito aggiuntivo di 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

Linea 85 del requests/models.py ( link ) trasforma il params oggetto in un dict pianura, piuttosto che il SortedDict avete passato. io non credo che si sarà in grado di fare ciò che si vuole, a meno che non si applica una patch la libreria.

self.params = dict(params or [])

ho scoperto che questo funziona in 1.2.3 così come 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'

E 'utilizzato con la versione 2.2.0:

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

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

Maggiori informazioni? controllo gentile nel qui .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top