简体   繁体   中英

How can I post http request instead of using cURL?

I am using anki-connect to communicate with Anki , a spaced repetition software.
In readme.md, it uses following command to get deck name.

curl localhost:8765 -X POST -d "{\"action\": \"deckNames\", \"version\": 5}"

It works right in my Windows system.
How can I use python instead of cURL?
I've tried this but get no luck.

import requests  
r = requests.post("http://127.0.0.1:8765", data={'action': 'guiAddCards', 'version': 5})
print(r.text)

When creating request you should:

  • provide Content-Type header
  • provide data in format that matches Content-Type header
  • make sure application supports the format

Both curl and python examples you gave sends request with Content-Type: application/x-www-form-urlencoded , the default one. The difference is curl passes string and python passes an array.

Let's compare curl and requests and what is really posted:

Curl

$ curl localhost -X POST -d "{\"action\": \"deckNames\", \"version\": 5}"

Headers:

Host: localhost
User-Agent: curl/7.52.1
Accept: */*
Content-Length: 37
Content-Type: application/x-www-form-urlencoded

Posted data:

[
    '{"action": "deckNames", "version": 5}'
]

Python

import requests  
r = requests.post("http://127.0.0.1", data={'action': 'guiAddCards', 'version': 5})
print(r.text)

Headers:

Host: 127.0.0.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.10.0
Content-Length: 28
Content-Type: application/x-www-form-urlencoded

Posted data:

[
    'action' -> 'guiAddCards',
    'version' -> '5',
]

As you can see, incorrect post data format breaks your app.

To be sure, that posted JSON data will be properly read by application you should make requests like that:

Curl

$ curl localhost:8765 -H 'Content-Type: application/json' -d '{"action": "deckNames", "version": 5}'

Python

import requests  
r = requests.post("http://127.0.0.1:8765", json={'action': 'guiAddCards', 'version': 5})
print(r.text)

I've tried following after digging and this works.
Can anybody share the reason. Thanks.

import requests
import json

#r = requests.post("http://127.0.0.1:8765", data={'action': 'guiAddCards', 'version': 5})
r = requests.post('http://localhost:8765', data=json.dumps({'action': 'guiAddCards', 'version': 5}))
print(r.text)

This is a reply to user2444791's answer. I can't reply with a comment because I don't have the reputation to comment (I'm new, please forgive a breech of etiquette!)

Without the exact error message, it's hard to be sure, but...

Looking at the Anki Connect API , it expects its POST-ed data to be a single string which contains a JSON object, not a key/value dictionary equivalent to that JSON object.

Every request consists of a JSON-encoded object containing an action, a version, and a set of contextual params.

Their example code (in Javascript): xhr.send(JSON.stringify({action, version, params}));

It might be as simple as sending your data in the wrong format. In the first example, you are sending a dictionary with the key/vale pairs already parsed. In the second example, you're sending a string for them to parse instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM