2013-06-21 52 views
2

我正在編寫一個客戶端界面來使用python中的restful web服務,不幸的是web服務需要自定義標頭出現在請求中。我一直在使用Requests for this,但是Web服務也要求頭文件在請求中按照特定的順序。我一直無法弄清楚請求是如何訂購標題的,並且看看是否有辦法能夠控制這種排序。Python HTTP請求與受控的HTTP標頭排序

如果有人有建議,我也願意在我的應用程序中使用除請求以外的其他模塊。

+2

如果我是你,我會向API的維護者提交一個錯誤報告,因爲這明顯違反了HTTP規範。 [RFC 2616 Section 4.2](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2)指出:'接收到不同字段名的頭部字段的順序並不重要。 '需要特定的頭文件訂單不僅不方便,而且不正確。 – rdlowrey

+0

完全同意,但不幸的是,這需要一段時間,我承受着完成這個項目的壓力。謝謝。 – user2509689

回答

1

你可以嘗試使用OrderedDict類存儲標題,而不是請求的默認之一:

>>> from collections import OrderedDict 
>>> from requests import Session 
>>> s = Session() 
>>> s.headers 
CaseInsensitiveDict({'Accept-Encoding': ... 'User-Agent': ... 'Accept': '*/*'}) 
>>> s.headers = OrderedDict([('User-Agent', 'foo-bar'), ('Accept', 'nothing')]) 
>>> s.headers 
OrderedDict([('User-Agent', 'foo-bar'), ('Accept', 'nothing')]) 
+0

不幸的是,即使它們在s.headers中正確,但是如果您發送請求r = s.get(url),然後使用r.request.headers檢查標頭,它們的順序與s.headers的順序不同。奇怪的。 – user2509689

+0

這不起作用,因爲請求使用它自己的CaseInsensitiveDict,它的子類字典。當你傳遞頭文件時,它會使用你提供的字典來初始化它自己的字典。 – num1

+0

@ num1:[文檔](http://docs.python-requests.org/en/master/user/advanced/#header-ordering)聲稱它應該足以覆蓋會話頭文件(使用'OrderedDict')。 [測試(2年)](https://github.com/requests/requests/blob/0eb9a4c1617909bbbb465a9987c7cba0f515eaa6/tests/test_requests.py#L434-L452)表明它應該工作。 – jfs

3

更新答案

關注以下版本的答案下面2.9.2。自版本2.9.2(2016年4月左右)使用OrderedDictworks again

老答案

它看起來就像是有可能前一段時間只使用內置功能(issue 179)。我認爲它不再是(issue 2057),其他原因之一在num1提到另一個評論。我已經使用了以下解決方案/解決方法。

import requests 
import collections 

class SortedHTTPAdapter(requests.adapters.HTTPAdapter): 
    def add_headers(self, request, **kwargs): 
     request.headers = collections.OrderedDict(
      ((key, value) for key, value in sorted(request.headers.items())) 
     ) 

session = requests.Session() 
session.mount("http://", SortedHTTPAdapter()) 

在示例中,標題只是排序,但可以用任何方式對它們排序。在通過requests代碼並閱讀方法的文檔字符串之後,我選擇了該方法:

添加連接所需的任何標頭。從v2.0開始,默認情況下,它不會執行任何操作 ,但留給子類爲 HTTPAdapter <requests.adapters.HTTPAdapter>類的用戶覆蓋。

對於絕對控制,可能會覆蓋send方法。

+0

它應該足以[使用'OrderedDict'](https://stackoverflow.com/questions/17239952/python-http-request-with-controlled-ordering-of-http-headers#comment79715787_17240379) – jfs

+0

我已經回答在對@ michaelmeyer的原始回答評論。 – wodny