2012-01-10 16 views
13

Tôi đang triển khai thư viện khách hàng cho một HTTP-API riêng sử dụng python requests. Các API (mà tôi không kiểm soát) hy vọng các tham số được theo một thứ tự nhất định, nhưng python-yêu cầu không tôn vinh một dict được sắp xếp như tham số.yêu cầu python: để nhận thông số

Đây là những gì tôi đã cố gắng:

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 

Đây là những gì tôi đang cố gắng để tránh:

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

Tại sao bạn sử dụng tham số 'data' thay vì' params' khi thực hiện yêu cầu? –

+0

@Piotr Dobrogost: Đó là lỗi khi tôi biên soạn ví dụ. – tback

+0

Tại sao đây lại là vấn đề? Các tham số GET thường được truy cập theo tên không theo thứ tự. –

Trả lời

9

Hiện nay yêu cầu không cho phép để làm điều này như bạn muốn. Đây là sự thiếu sót của khóa học sẽ là fixed. Tuy nhiên như params tham số có thể mất không chỉ từ điển nhưng byte cũng bạn sẽ có thể làm điều gì đó ở giữa:

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

này không làm việc như tôi thấy do lỗi trong dòng 85 của models.py: self.params = dict(params or [] . tôi nêu ra vấn đề này trong vấn đề Wrong handling of params given as bytes object

+0

Cảm ơn, cuối cùng tôi đã đánh dấu đây là giải pháp vì nó cung cấp giải pháp được áp dụng trong tương lai gần. – tback

+0

@TillBackhaus Đã [cố định] (https://github.com/kennethreitz/requests/commit/9e953f33209545bbbd338e06fb2abc2c62c13212). –

+0

Phiên bản này hoạt động như thế nào? Khi tôi thử nó trong cả hai '1.2.3' và' 2.0.0', 'requests.get ('http://example.org/private_api', params = urlencode (params)). Request.body' trả về' None ' – Jian

1

Dòng 85 của requests/models.py (link) lần lượt các đối tượng params thành một đồng bằng dict, chứ không phải là SortedDict bạn thông qua vào. Tôi không nghĩ rằng bạn sẽ có thể làm những gì bạn muốn , trừ khi bạn vá thư viện.

self.params = dict(params or []) 
+0

Xem xét các tùy chọn tại tôi nghĩ rằng tôi sẽ phải đi với những gì tôi đã cố gắng để tránh sau đó. Cảm ơn bạn. – tback

17

Yêu cầu lib bây giờ hỗ trợ out-of-the-box này: Để có được thông số đặt hàng, bạn sử dụng một chuỗi các bộ dữ liệu hai giá trị thay thế. Điều này loại bỏ yêu cầu bổ sung của 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 
0

tôi thấy rằng công trình này trong 1.2.3 cũng như 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' 
1

Nó sử dụng với phiên bản 2.2.0:

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

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

More chi tiết? Vui lòng kiểm tra trong here.

+0

Điều này không bảo vệ thứ tự các thông số được yêu cầu bởi OP. –