Python请求POST做GET?
我使用Python 2.7.5,Django的1.7,要求2.4.1,并做一些简单的测试。但是,它看起来像我调用requests.post时,该方法是做一个GET。Python请求POST做GET?
我的代码,跟一个REST的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 /采购的新版本),我必须设置其他参数?这是一个缓存问题吗?任何调试技巧?我尝试重新安装请求,并将Django回滚到1.6.5,但没有任何工作......一定很简单。 - 谢谢!
======更新1个========
只是巩固了一些调试信息的那马亭这里建议:
(Pdb) requests.post.__name__
'post'
步入请求/ API。 PY>柱()定义:
(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)
钻孔向下进入请求()方法:
(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.
需要明确的是,每当收到的请求重定向(有一定的status code),我们必须对请求执行某些转换。
在这样的情况下,当你看到一些很意外的最好的调试技巧是重试您的请求,但与allow_redirects=False
。这将立即返回30倍响应。另外,您还可以检查r.history
,看看是否有随访任何30X响应。在这种情况下,你可能会看到类似
>>> r.request.method
'GET'
>>> r.history
[<Response [302]>,]
>>> r.history[0].request.method
'POST'
我们知道,这样做可能会导致使用者意外的行为(因为它只是做给你),但它在网络上操作的唯一正确途径。
我希望这可以帮助你理解为什么这发生超出了事实,这是一个重定向,并希望它可以让你和其他工具,以在未来的调试此。
感谢您的明确解释!找到这个之后,我做了一些关于重定向的阅读,并且更好地理解了为什么图书馆的行为如此... – user 2014-10-02 14:54:55
感谢Martijn提供了一些调试技巧!这个问题是REST风格的API被重定向我从http://到https://,这引起了库返回“第二”请求(GET)...
您发布的代码将不*生成GET,它将生成POST。你是否100%确定你正在执行正确的代码路径? – 2014-10-01 19:42:04
这是我的单元测试的一部分,我正在逐行执行,所以我99%肯定这是它遵循的代码路径 - 如果有其他方法检查以消除1%,我是不知道如何,但会很乐意去做... – user 2014-10-01 19:46:32
顺便说一下,我同意并理解上面的代码应该产生一个POST ...所以我认为别的是错的(1%)。如果我使用错误的代码路径,还有什么其他方法可以找到我正在执行的路径(除了pdb)? – user 2014-10-01 19:48:40