How do I send a POST request as a JSON?
Solution 1
If your server is expecting the POST request to be json, then you would need to add a header, and also serialize the data for your request...
Python 2.x
import json
import urllib2
data = {
'ids': [12, 3, 4, 5, 6]
}
req = urllib2.Request('http://example.com/api/posts/create')
req.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(req, json.dumps(data))
Python 3.x
https://stackoverflow.com/a/26876308/496445
If you don't specify the header, it will be the default application/x-www-form-urlencoded
type.
Solution 2
I recommend using the incredible requests
module.
http://docs.python-requests.org/en/v0.10.7/user/quickstart/#custom-headers
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
Solution 3
For python 3.4.2, I found the following will work:
import urllib.request
import json
body = {'ids': [12, 14, 50]}
myurl = "http://www.testmycode.example"
req = urllib.request.Request(myurl)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(body)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
req.add_header('Content-Length', len(jsondataasbytes))
response = urllib.request.urlopen(req, jsondataasbytes)
Solution 4
This works perfect for Python 3.5
, if the URL contains Query String / Parameter value,
Request URL = https://bah2.example/ws/rest/v1/concept/
Parameter value = 21f6bb43-98a1-419d-8f0c-8133669e40ca
import requests
url = 'https://bahbah2.example/ws/rest/v1/concept/21f6bb43-98a1-419d-8f0c-8133669e40ca'
data = {"name": "Value"}
r = requests.post(url, auth=('username', 'password'), json=data)
print(r.status_code)
Solution 5
Here is an example of how to use urllib.request object from Python standard library.
import urllib.request
import json
from pprint import pprint
url = "https://app.close.com/hackwithus/3d63efa04a08a9e0/"
values = {
"first_name": "Vlad",
"last_name": "Bezden",
"urls": [
"https://twitter.com/VladBezden",
"https://github.com/vlad-bezden",
],
}
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
data = json.dumps(values).encode("utf-8")
pprint(data)
try:
req = urllib.request.Request(url, data, headers)
with urllib.request.urlopen(req) as f:
res = f.read()
pprint(res.decode())
except Exception as e:
pprint(e)
TIMEX
Updated on November 05, 2021Comments
-
TIMEX over 2 years
data = { 'ids': [12, 3, 4, 5, 6 , ...] } urllib2.urlopen("http://abc.com/api/posts/create",urllib.urlencode(data))
I want to send a POST request, but one of the fields should be a list of numbers. How can I do that ? (JSON?)
-
zakdances over 10 yearsThis gives me
TypeError: post() takes from 1 to 2 positional arguments but 3 were given
-
psukys over 7 yearsin your code snipper, headers variable stays unused
-
Omar Jandali over 6 yearsI have a question. is it possible to add multiple items in the header... like content type & client-id... @jdi
-
jdi over 6 years@OmarJandali, just call
add_header()
again, for each header you want to add. -
Omar Jandali over 6 yearsi have the following coded but it is not printing anything. it was supposed to print the url and headers but nothing was printed...
req = urllib.Request('http://uat-api.synapsefi.com') req.add_header('X-SP-GATEWAY', 'client_id_asdfeavea561va9685e1gre5ara|client_secret_4651av5sa1edgvawegv1a6we1v5a6s51gv') req.add_header('X-SP-USER-IP', '127.0.0.1') req.add_header('X-SP-USER', '| ge85a41v8e16v1a618gea164g65') req.add_header('Content-Type', 'application/json') print(req)
... -
Omar Jandali over 6 yearsurllib2 was not recognized so i just used urllib. i am also getting an error with the request.
The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead.
@jdi -
jdi over 6 years@OmarJandali, please keep in mind that this answer was originally given in 2012, under python 2.x. You are using Python3 so the imports will be different. It would now be
import urllib.request
andurllib.request.Request()
. Furthermore, printing the req object does nothing interesting. You can clearly see the headers have been added by printingreq.headers
. Beyond that, I am not sur why it isn't working in your application. -
Omar Jandali over 6 yearsSo i have two lines that i made changes to
response = urllib.request.Request(req, json.dumps(data))
andreq = urllib.request.Request('http://uat-api.synapsefi.com')
. i am getting a message sayingunknown url type: 'urllib.request.Request object at 0x00000250B05474A8'
from the second line that i made changes to... what is the way fro me to change the url type @jdi -
jdi over 6 years@OmarJandali, you aren't calling
urlopen()
like the original example. That is why you are getting an error. See: pastebin.com/1gUdGYcP -
Omar Jandali over 6 yearsLet us continue this discussion in chat.
-
Omar Jandali over 6 yearsThan you so much, it is working and sending a response. it is sending a response in the wrong format
POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
-
Shalin LK over 6 yearsPython3.6.2 this worked. Only adding header with req.add_header(...) worked for me.
-
Kuzeko about 6 yearsThe python3 version is the one here: stackoverflow.com/a/26876308/5973334 – better merge it with the accepted answer
-
jdi about 6 years@Kuzeko, thanks. I have added that reference to my answer
-
Jethro about 4 yearsNote that this will result in POSTed json with single quotes, which is technically invalid.
-
jdhao about 4 years@Jethro Have you observed errors when using single quotes? It is valid to use single quotes in Python. Personally, I haven't met any issues regarding this.
-
Jethro about 4 yearsAah apologies I was mistaken, I thought my server was receiving single-quoted JSON but It turned out to be a separate issue and some misleading debugging. Cheers, this is much tidier than having to specify the header manually!
-
rgov over 2 yearsThis is an incorrect answer. The
data=data
parameter sends a form-encoded request, which is not JSON. Usejson=data
instead. -
rgov over 2 yearsNote: This answer is very old and
urllib2
has been removed in Python 3. Look for other examples usingurllib
orrequests
. -
rgov over 2 yearsIt is much more succinct to just use
json=payload
(which may have been introduced since this answer was written long ago) without specifying the header or callingjson.dumps()
. See other answers on this page. -
rgov over 2 yearsYou do not need to specify the
Content-Length
header, it will be calculated byurllib
automatically. -
rgov over 2 yearsThis answer is insecure. Do not pass
verify=False
, which disables certificate validation and opens your code up to man-the-middle attacks. -
rgov over 2 yearsI removed
verify=False
from the code sample to resolve the above comment. -
Apurva Singh almost 2 yearsworks great using standard library urllib. Don't forget the data in Request(url, data, headers), otherwise it would look like a GET to the server.