簡體   English   中英

Python請求POST進行GET?

[英]Python Requests POST doing a GET?

我正在使用Python 2.7.5,Django 1.7,請求2.4.1,並進行一些簡單的測試。 但是,似乎當我調用requests.post時,該方法正在執行GET。

我的代碼,與RESTful API交談。 請注意,POST命令通過Hurl.it與此有效負載和端點一起工作:

def add_dummy_objective(self):
    """
    To the bank
    """
    payload = {
        'displayName': {
            'text': self._test_objective
        },
        'description': {
            'text': 'For testing of API Middleman'
        },
        'genusTypeId': 'DEFAULT'
    }
    obj_url = self.host + self.bank_id + '/objectives/?proxyname=' + self._admin_key
    req = requests.post(obj_url, data=json.dumps(payload), headers=self.headers)
    return req.json()

我將標題設置為json:

self.headers = {
    'Content-Type'  : 'application/json'
}

我沒有創建一個新目標(正如預期的那樣使用POST),而是獲得了目標列表(我對GET的期望)。 使用pdb,我看到:

(Pdb) req.request
<PreparedRequest [GET]>
(Pdb) req.request.method
'GET'

這怎么翻了? 我之前使用過Python請求庫沒有任何問題,所以我不確定我是否遺漏了一些明顯的東西或者是否(使用較新版本的Django / Requests)我必須設置另一個參數? 這是一個緩存問題嗎? 任何調試技巧? 我已經嘗試重新安裝請求,並將Django回滾到1.6.5,但沒有任何作用......必須簡單。 - 謝謝!

======更新1 ========

只需合並Martijn在此提出的一些調試信息:

(Pdb) requests.post.__name__
'post'

進入requests / api.py> post()定義:

(Pdb) l
 88         :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
 89         :param \*\*kwargs: Optional arguments that ``request`` takes.
 90         """
 91         import pdb
 92         pdb.set_trace()
 93  ->     return request('post', url, data=data, **kwargs)

深入研究request()方法:

(Pdb) method
'post'
(Pdb) l
 43           >>> req = requests.request('GET', 'http://httpbin.org/get')
 44           <Response [200]>
 45         """
 46         import pdb
 47         pdb.set_trace()
 48  ->     session = sessions.Session()
 49         return session.request(method=method, url=url, **kwargs)

在session.request中還有一個層:

(424)request()
-> method = builtin_str(method)
(Pdb) method
'post'
(Pdb) l
419             :param cert: (optional) if String, path to ssl client cert file (.pem).
420                 If Tuple, ('cert', 'key') pair.
421             """
422             import pdb
423             pdb.set_trace()
424  ->         method = builtin_str(method)
425
426             # Create the Request.
427             req = Request(
428                 method = method.upper(),
429                 url = url,

退到方法的最后,實際發出請求,我的“准備”是一個POST,但我的resp是一個GET:

(Pdb) prep
<PreparedRequest [POST]>
(Pdb) n
-> return resp
(Pdb) resp
<Response [200]>
(Pdb) resp.request
<PreparedRequest [GET]>
(Pdb) l
449                 'allow_redirects': allow_redirects,
450             }
451             send_kwargs.update(settings)
452             resp = self.send(prep, **send_kwargs)
453
454  ->         return resp
455
456         def get(self, url, **kwargs):
457             """Sends a GET request. Returns :class:`Response` object.
458
459             :param url: URL for the new :class:`Request` object.

要清楚,每當請求收到重定向(具有特定狀態代碼 )時,我們必須對請求執行某些轉換。

在這種情況下,當您看到非常意外的情況時,最好的調試技巧是重試您的請求,但使用allow_redirects=False 這將立即返回30x響應。 或者,您也可以檢查r.history以查看是否有任何30x響應被遵循。 在這種情況下,你可能會看到類似的東西

>>> r.request.method
'GET'
>>> r.history
[<Response [302]>,]
>>> r.history[0].request.method
'POST'

我們知道這樣做可能會導致用戶意外行為(就像它對你做的那樣),但這是在網絡上運行的唯一正確方法。

我希望這可以幫助您理解為什么這發生在它是重定向的事實之外,並且希望它能夠為您和其他人提供將來調試它的工具。

感謝Martijn的一些調試技巧! 問題是RESTful API將我從http://重定向到https://,導致庫返回“第二個”請求(GET)...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM