将curl调用转换为python请求

将curl调用转换为python请求

本文介绍了将curl调用转换为python请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是curl调用的样子:(取自:)

  curl -X POST https://secure.payu.com/api/v2_1/orders \ 
-H内容类型:application / json \
-H授权: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,
产品:[
{
name:笔记本电脑无线鼠标 ,
unitPrice: 15000,
quantity: 1
},
{
name: HDMI cable,
unitPri ce: 6000,
quantity: 1
}
]
}'

这是我在请求中写的内容:

  import json 
导入请求
标头= {
'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市场,
currencyCode: PLN,
totalAmount: 21000,
产品:[
{
名称:笔记本电脑无线鼠标,
单价: 15000,
数量: 1
},
{
name: HDMI cable,
unitPrice: 6000,
quantity: 1
}
]
}

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

卷曲作为响应打印出来:

  { orderId: V6GRPMNRLRLR160429GUEST000P01,状态:{ statusCode: SUCCESS}, redirectUri: https://secure.payu.com/pl/standard/co/summary?sessionId=HtnLqVtBJ5tcOKG2nX03TKwAXOYtXPHe&merchantPosId=145227&timeStamp=1461948331350& ; apiToken = 9f31fcd1d0d1c5fde8aa57c2b16b5d6bbdfe81543a5f6a12cd39955a487fdaab} 

而python请求:

  /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:315:SNIMissingWarning:已发出HTTPS请求,但是TLS的SNI(主题名称指示)扩展名在此平台上不可用。这可能会导致服务器出示不正确的TLS证书,从而可能导致验证失败。有关更多信息,请参阅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:真正的SSLContext对象不可用。这会阻止urllib3正确配置SSL,并可能导致某些SSL连接失败。有关更多信息,请参阅https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning。
InsecurePlatformWarning
追溯(最近一次通话):
文件 /home/ubuntu/workspace/src/billing/testapi.py,第30行,在< module>中
print(resp2.json())
文件 /usr/local/lib/python2.7/dist-packages/requests/models.py,行808,在json
中返回complexjson.loads(self.text,** kwargs)
文件 /usr/lib/python2.7/dist-packages/simplejson/__init__.py,第488行,在加载
中,返回_default_decoder。解码
文件 /usr/lib/python2.7/dist-packages/simplejson/decoder.py,第370行,用于解码
obj,end = self.raw_decode(b)
文件 /usr/lib/python2.7/dist-packages/simplejson/decoder.py,行389,在raw_decode
中返回self.scan_once(s,idx = _w(s,idx).end())
simplejson.scanner.JSONDecodeError:期望值:第8行第1列(字符7)

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

解决方案

该站点以 302状态码进行响应,其中包括位置标头:

 >> resp = request.post('https://secure.payu.com/api/v2_1/orders',headers = headers,json = data)
>>响应历史
[<响应[302]>,<响应[302]>]
>> resp.history [0] .headers ['location']
'https://secure.payu.com/pl/standard/co/summary?sessionId=rrQ97fR2bxQJhUqCDORCbRa0uA4WlxJi&merchantPosId=145227&timeStamp=1461950205252&showShow 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 = f3599eca78ad55a16d84608b2b7b&b7b&b6b&b; c76c7b&b&b; bcb&bc&bc&bc&b2b&bcb&bc&bcb&bc&bc&bc&bc&bc&b2b&bc&bc&bc&bc&bc&bc&b2&bc&bc&bf&bc&b2&b&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&bc&b2&bc&bc&bc&bc&bc&b2b&女人

您可以通过查看 response.history 列表来查看重定向历史记录(如我上面所做的那样),该列表包含先前的请求。 resp.history [0] 是此处的初始响应。请参见(单击 Headers ,然后添加 Accept-Encoding 标头,并为



您应该将其视为网站中的错误,因为指定标头是完全正常的事情。实际上,Python httplib 库(由 requests 间接使用)设置了默认值如果您自己省略该标题,则请求甚至都无法关闭。因此,我已将此错误报告给PayU。



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

  >>> resp = request.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=5962ef901010ca4f8ef64916192ec2b2d2e2c2e2b3c3dc3d3e6e6e6e6e6e6e6e8c6e8c6e8c6e8c6e8c人>

但是请注意,忽略302可能会干扰正常的状态代码,我看到。


I've got a problem converting curl request into Python requests call:

here is how curl call looks like: (taken from: 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"
        }
    ]
}'

and here is what I wrote in requests:

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

curl as a response prints out:

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

whereas python requests:

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

does anyone know why it's not working with requests ? thanks

解决方案

The site responds with a 302 status code, including a Location header:

>>> 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"}'

You can look at the redirection history (like I did above) by looking at the response.history list, which contains preceding requests. resp.history[0] was the initial response here. See Redirection and History in the documentation.

Note that the data is right there on the initial response.

The site does this when you use any Accept-Encoding header; you get the same result if you add

-H "Accept-Encoding: gzip, deflate"

to the curl command, or by adding the same header (with any value) to the supplied payu.apiari.io console (click Headers, then add the Accept-Encoding header and add a value for the header).

You should consider this a bug in the site, as specifying that header is a perfectly normal thing to do. In fact, the Python httplib library (used indirectly by requests) sets a default value for that header if you omit it yourself, so this is not something requests can even switch off. As such, I've reported this to PayU as a bug.

As a work-around, you can use the response.history[0] reference, or better yet, tell requests not to follow the redirect in the first place:

>>> 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'}

But take care that ignoring the 302 may interfere with the normal status codes, I see that a 302 may indicate that additional security info is required.

这篇关于将curl调用转换为python请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 10:55