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