POST request from python to nodeJS server

Question:

I am trying to send a post request from python to my nodeJS server. I can successfully do it from client-side js to nodeJS server using the fetch API but how can I achieve this with python? What I tried below is sending the post request successfully but the data/body attached to it is not reaching the server. What am I doing wrong and how can I fix it? Thanks in advance.

NOTE: All my nodeJS routes are set up correctly and work fines!

//index.js

'use strict';
const express = require('express')
const app = express()
const PORT = 5000

app.use('/js', express.static(__dirname + '/public/js'))
app.use('/css', express.static(__dirname + '/public/css'))
app.set('view engine', 'ejs')
app.set('views', './views')
app.use(cookie())
app.use(express.json({
  limit: '50mb'
}));

app.use('/', require('./routes/pages'))
app.use('/api', require('./controllers/auth'))

app.listen(PORT, '127.0.0.1', function(err) {
  if (err) console.log("Error in server setup")
  console.log("Server listening on Port", '127.0.0.1', PORT);
})

//server file
//served on http://127.0.0.1:5000/api/server

const distribution = async(req, res) => {
  //prints an empty object
  console.log(req.body)
}

module.exports = distribution;

//auth
const express = require('express')
const server = require('./server')

const router = express.Router()

router.post('/server', server)

module.exports = router;

//routes
const express = require('express')
const router = express.Router()

router.get('/', loggedIn, (req, res) => {
  res.render('test', {
    status: 'no',
    user: 'nothing'
  })
})

#python3
import requests

API_ENDPOINT = "http://127.0.0.1:5000/api/server"
  
data = '{"test": "testing"}'

response = requests.post(url = API_ENDPOINT, data = data)

print(response)
Asked By: seriously

||

Answers:

Since you are manually passing the request as a string you may need to specify also the content-type so that Express middleware can recognise and parse it as JSON.

See express.json documentation

Returns middleware that only parses JSON and only looks at requests where the Content-Type header matches the type option. This parser accepts any Unicode encoding of the body and supports automatic inflation of gzip and deflate encodings.

you could do it like this:

headers = {'Content-type': 'application/json'}
data = '{"test": "testing"}'

response = requests.post(url = API_ENDPOINT, data = data, headers = headers)

A better idea is to use instead (if your requests version supports it) the json parameter instead of data as shown in How to POST JSON data with Python Requests? and let the requests framework set the correct header for you:

data = {'test': 'testing'}

response = requests.post(url = API_ENDPOINT, json = data)
Answered By: pqnet

Have you tried passing the request payload directly as a json instead of converting it to string? Like @pqnet Has mentioned, Python’s request library will automatically add content-type header to your post request.

import requests

API_ENDPOINT = "http://127.0.0.1:5000/api/server"
  
data = {"test": "testing"}

response = requests.post(url = API_ENDPOINT, json = data)

print(response)
Answered By: Darkness
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.