How can I POST a JSON to an Express server with python module "requests"?

Question:

So, I’m trying to post a JSON to a Node.JS server running Express with Python using the "requests" module. I’ve made a lot of tries, all of them failed.

Closest I got was this:

Server code:

const fs = require('fs');
const express = require('express');
const app = express();

app.use(express.static("public"));
app.use(express.json());

app.get('/', function(_, res) {
    var data = fs.readFileSync("./get.json");
    res.json(JSON.parse(data));
});

app.post('/', function(req, res) {
    fs.writeFile('./get.json', JSON.stringify(req.body), err => {
        if (err) {
            res.json(JSON.parse('{"status":false,"err":"%s"}', (err)));
        } else {
            res.json(JSON.parse('{"status":true}'));
        };
    });
});

app.listen(3000, function() {
    console.log(`Up and running on port 3000.`);
});

Python script:

import requests
data = {'test':'Hello World!'}
response = requests.post("XXXXX.herokuapp.com/", data=data)

It sort of works, but on a GET request, it returns a blank JSON ({}), same when logging req.body on the POST request. I want it to return what was sent in the POST request ({'test':'Hello World!'}).

Asked By: Lucas

||

Answers:

Passing the data keyword arg does not convert the data to JSON. Instead use the json keyword arg. This will convert your dictionary to a JSON serialized string that the server can parse.

import requests
data = {'test':'Hello World!'}
response = requests.post("XXXXX.herokuapp.com/", json=data)

What’s the difference? We can see what happens by looking at the PreparedRequest object that is created before the request is sent.

import requests

### using data param
req = requests.Request('POST', 'http://localhost:8000', data={'test': 'hello world'})
preq = req.prepare()
preq.body
# returns:
'test=hello+world'

req = requests.Request('POST', 'http://localhost:8000', json={'test': 'hello world'})
preq = req.prepare()
preq.body
# returns:
b'{"test": "hello world"}'

The first is not parsable as JSON, where the second is proper JSON.

Answered By: James

It looks like the issue may be with how you are sending the data in the Python script. When sending data with a POST request using the "requests" module, you should use the "json" parameter instead of the "data" parameter. This will set the "Content-Type" header to "application/json" and serialize the JSON data in the request body.

Try the code below,

import requests

data = {'test': 'Hello World!'}
response = requests.post("XXXXX.herokuapp.com/", json=data)
print(response.json())

This should send the JSON data in the request body and allow the server to parse it correctly.

Answered By: nimantha fernando