将curl调用转换为python请求

时间:2016-04-29 16:46:21

标签: python curl python-requests

我在将curl请求转换为Python请求调用时遇到了问题:

这里是curl调用的样子:(取自:http://developers.payu.com/en/restapi.html#creating_new_order_api

curl -X POST https://secure.payu.com/api/v2_1/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
-d '{
    "notifyUrl": "https://your.eshop.com/notify",
    "customerIp": "127.0.0.1",
    "merchantPosId": "145227",
    "description": "RTV market",
    "currencyCode": "PLN",
    "totalAmount": "21000",
    "products": [
        {
            "name": "Wireless Mouse for Laptop",
            "unitPrice": "15000",
            "quantity": "1"
        },
        {
            "name": "HDMI cable",
            "unitPrice": "6000",
            "quantity": "1"
        }
    ]
}'

以下是我在请求中写的内容:

import json
import requests
headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd',
}

data = {
    "notifyUrl": "https://your.eshop.com/notify",
    "customerIp": "127.0.0.1",
    "merchantPosId": "145227",
    "description": "RTV market",
    "currencyCode": "PLN",
    "totalAmount": "21000",
    "products": [
        {
            "name": "Wireless Mouse for Laptop",
            "unitPrice": "15000",
            "quantity": "1"
        },
        {
             "name": "HDMI cable",
             "unitPrice": "6000",
             "quantity": "1"
        }
    ]
}

resp2 = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data)
print(resp2.json())

作为回应打印出来的卷曲:

{"orderId":"V6GRPMNRLR160429GUEST000P01","status":{"statusCode":"SUCCESS"},"redirectUri":"https://secure.payu.com/pl/standard/co/summary?sessionId=HtnLqVtBJ5tcOKG2nX03TKwAXOYtXPHe&merchantPosId=145227&timeStamp=1461948331350&showLoginDialog=false&apiToken=9f31fcd1d0d1c5fde8aa57c2b16b5d6bbdfe81543a5f6a12cd39955a487fdaab"}

而python请求:

/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:315: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.        
  SNIMissingWarning                                                                                                                                                                                                       
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:120: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.                                                                           
  InsecurePlatformWarning                                                                                                                                                                                                 
Traceback (most recent call last):                                                                                                                                                                                        
  File "/home/ubuntu/workspace/src/billing/testapi.py", line 30, in <module>                                                                                                                                              
    print(resp2.json())                                                                                                                                                                                                   
  File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 808, in json                                                                                                                                     
    return complexjson.loads(self.text, **kwargs)                                                                                                                                                                         
  File "/usr/lib/python2.7/dist-packages/simplejson/__init__.py", line 488, in loads                                                                                                                                      
    return _default_decoder.decode(s)                                                                                                                                                                                     
  File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode                                                                                                                                      
    obj, end = self.raw_decode(s)                                                                                                                                                                                         
  File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 389, in raw_decode                                                                                                                                  
    return self.scan_once(s, idx=_w(s, idx).end())                                                                                                                                                                        
simplejson.scanner.JSONDecodeError: Expecting value: line 8 column 1 (char 7)   

有谁知道为什么它不能处理请求?感谢

1 个答案:

答案 0 :(得分:1)

网站以 302状态代码响应,包括位置标头:

>>> resp = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data)
>>> resp.history
[<Response [302]>, <Response [302]>]
>>> resp.history[0].headers['location']
'https://secure.payu.com/pl/standard/co/summary?sessionId=rrQ97fR2bxQJhUqCDORCbRa0uA4WlxJi&merchantPosId=145227&timeStamp=1461950205252&showLoginDialog=false&apiToken=f3599eca78ad55a16d84608e69f3ac7458b782598b064b337be07e8bd6c2c1d5'
>>> resp.history[0].text
u'{"orderId":"Z9W2H77TVD160429GUEST000P01","status":{"statusCode":"SUCCESS"},"redirectUri":"https://secure.payu.com/pl/standard/co/summary?sessionId=rrQ97fR2bxQJhUqCDORCbRa0uA4WlxJi&merchantPosId=145227&timeStamp=1461950205252&showLoginDialog=false&apiToken=f3599eca78ad55a16d84608e69f3ac7458b782598b064b337be07e8bd6c2c1d5"}'

您可以通过查看包含先前请求的response.history列表来查看重定向历史记录(就像我上面所做的那样)。 resp.history[0]是最初的回复。请参阅文档中的Redirection and History

请注意,初始响应中的数据就在那里

当您使用任何 Accept-Encoding标头时,网站会执行此操作;如果添加

,您会得到相同的结果
-H "Accept-Encoding: gzip, deflate"

curl命令,或者向supplied payu.apiari.io console添加相同的标头(带有任何值)(单击标题,然后添加Accept-Encoding标题并为标题添加一个值。

您应该将此视为网站中的错误,因为指定该标头是完全正常的事情。事实上,Python httplib库(由requests间接使用)如果您自己省略它,则为该标题设置默认值,因此这不是requests甚至可以关掉。因此,我已将此报告给PayU作为错误。

作为解决方法,您可以使用response.history[0]引用,或者更好的是,告诉请求不要首先遵循重定向:

>>> resp = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data, allow_redirects=False)
>>> resp.json()
{u'orderId': u'NBWTP5WNKK160429GUEST000P01', u'status': {u'statusCode': u'SUCCESS'}, u'redirectUri': u'https://secure.payu.com/pl/standard/co/summary?sessionId=PcvceJHf5En60Dier5gKxCyExiva4qh0&merchantPosId=145227&timeStamp=1461950329704&showLoginDialog=false&apiToken=5962ef901010ca4f8ef6491619217c060f4d53ed0d8e4eadb513d4e0811fc992'}

但请注意忽略302可能会干扰正常状态代码,我看到a 302 may indicate that additional security info is required