Uploading file and data from Python to Node.js in POST - python

How do I send a file to Node.js AND parameter data in POST. I am happy to use any framework. I have attempted it with formidable but I am happy to change.
In my attempt, the file sends, but req.body is empty
Python code to upload:
with open('fileName.txt', 'rb') as f:
payLoad = dict()
payLoad["data"] = "my_data"
r = requests.post('http://xx.xx.xx.xx:8080/sendFile',json = payLoad, files={'fileName.txt': f})
Server Side Node.js:
var express = require('express');
var formidable = require('formidable');
var app = express();
var bodyParser = require('body-parser');
app.use( bodyParser.json() );
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/sendFile', function (req, res){
console.log(req.body )
// req.body is empty

I don't know how to correctly send the file using python, but to receive file with node.js you can use express-fileupload
var fileUpload = require('express-fileupload');
app.use(fileUpload());
app.post('/upload', function(req, res) {
if (!req.files)
return res.status(400).send('No files were uploaded.');
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let sampleFile = req.files.sampleFile;
// Use the mv() method to place the file somewhere on your server
sampleFile.mv('/somewhere/on/your/server/filename.jpg', function(err) {
if (err)
return res.status(500).send(err);
res.send('File uploaded!');
});
});
https://www.npmjs.com/package/express-fileupload

Related

Audio file input from node file to python file

I want to upload a .wav file from react frontend to node server and then send the file to a python file for speech recognition.
I used multer to get the file in the post route. The file I get looks like this.
{
"fieldname": "file",
"originalname": "00f0204f_nohash_0.wav",
"encoding": "7bit",
"mimetype": "audio/wave",
"destination": "./public/",
"filename": "IMAGE-1635358708022.wav",
"path": "public\\IMAGE-1635358708022.wav",
"size": 32044
}
Now I want to fork a child process for python from index.js and want to sent the file for ASR.
The python file code looks like this:
import speech_recognition as sr
def read_in():
lines = sys.stdin.readlines()
return json.loads(lines[0])
def main():
a = read_in()
r = sr.Recognizer()
with sr.AudioFile(a) as source:
audio_text = r.listen(source)
try:
text = r.recognize_google(audio_text)
print('Conversion Started')
print(text)
except:
print('Error Occurred - Try Again')
How should I send the uploaded file from node to this python file for computation? I am new at this, so I am really confused.
if you are post processing the file, then get the file content with REST API:
# Postman generated
import http.client
host = "ur ip"
path = "server path:port" # port match as the express server
def webhooktriggered(path): # i haven't done any project about py web before, so goodluck
conn = http.client.HTTPSConnection(host)
payload = ''
headers = {}
conn.request("GET", path, payload, headers)
res = conn.getresponse()
data = res.read()
return (data.decode("utf-8"))
before, stream your media with express:
// Original: https://www.codegrepper.com/code-examples/javascript/node+js+express+sendfile+fs+filestream
var http = require('http'),
fileSystem = require('fs'),
path = require('path');
http.createServer(function(request, response) {
var filePath = path.join(__dirname, 'pathto/yourfilehere.wav');
var stat = fileSystem.statSync(filePath);
response.writeHead(200, {
'Content-Type': 'audio/x-wav', // change to whatever u want
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream(filePath);
// We replaced all the event handlers with a simple call to readStream.pipe()
readStream.pipe(response);
})
.listen(2000); //as soon we will use this port in rest client
Trigger when process, using axios
const axios = require('axios')
function uploadSuccess(path){ // must be the streamed express media path, so python rest can download it then
axios.get('http://pythonbackserverip/?path=' + encodeURI(path))
.then({
console.log("upload successfully!")
})
}
note: my code is not accurate, modify it before use

Retrieve file from mongoDB using python

I have doc file stored in mongodb. I want to retrieve stored doc file on mongoDB using python. Any suggestion will really be helpful. I'm unable to find article to move forward. All I could find is uploading file through python and retrieving through python. But I want to retrieve file stored on mongoDB which is not created on python but retrieving through python. P.S.: I stored file on mongodb gridfs using express js.
Upload.JS:: JS used to upload file on mongodb gridfs .
const util = require("util");
const multer = require("multer");
const GridFsStorage = require("multer-gridfs-storage");
const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const mongoURI ='mongodb://localhost:27017/file_uploaded_new';
const promise = mongoose.connect(mongoURI, { useNewUrlParser: true });
const conn = mongoose.connection;
let gfs;
conn.once('open',() => {
gfs = Grid(conn, mongoose.mongo);
gfs.collection('uploads');
});
var storage = new GridFsStorage({
db: promise,
options: {useNewUrlParser: true, useUnifiedTopology: true },
file: (req, file) => {
return new Promise((resolve, reject) => {
if (file.mimetype === 'application/vnd.openxmlformats-
officedocument.wordprocessingml.document') {
resolve({
bucketName: 'words',
filename: `${file.originalname}`
})
} else {
reject(Error("File type has been rejected"));
}
});
}
});
var uploadFile = multer({storage: storage}).single("file");
var uploadFilesMiddleware = util.promisify(uploadFile);
module.exports = uploadFilesMiddleware;
I have successfully uploaded docx file in MongoDB. How can I retrieve the uploaded word file using python script?

Sending a group of large buffers from express to flask

I'm trying to send a group of .mp4 files first from a web browser client, then to express, then to flask. This code might look simple, but it has taken literally days to get this far, because nobody on the internet has posted an example of how to do this with large files (.mp4 video files), and to be honest, there are a lot of inconsistencies in using these libraries.
I think it might be an encoding error from express to Flask, however. The actual data seems to be being transferred, but ffmpeg doesn't recognize the received .mp4 files as a valid video file.
From the client, I send an XHR request like this:
var formData = new FormData();
for(var x=0; x< datas.videoDatas.length; x++){
// data.videoDatas[x] is a blob of a .mp4 file. it can be played
formData.append(x+"_video.mp4",datas.videoDatas[x]);
}
var xhr = new XMLHttpRequest();
xhr.open("POST", 'http://localhost:3000/uploadVid', true);
xhr.onreadystatechange = function() {
if(this.readyState == XMLHttpRequest.DONE && this.status == 200) {
console.log(xhr.response);
}
}
xhr.onload=console.log;
xhr.send(formData);
The express server at port 3000 receives the post request using the "multer" library. Data is stored into memory as a buffer.
var express = require('express');
var multer=require("multer");
var request=require("request")
var app = express();
var storage = multer.memoryStorage();
const upload = multer({
storage: storage
}).any();
app.post('/uploadVid',function(req,res){
var originalResponse=res;
console.log("begin upload");
upload(req, res, function(err) {
console.log("begin upload to flask server");
var requestStruct={
url: 'http://localhost:3001/receiveUpload2?numFiles='+req.files.length,
method: 'POST',
form: {
}
}
for(var x=0; x < req.files.length; x++){
var testBuffer=req.files[x].buffer; // should be a buffer of the .mp4 file
//testBuffer = new Buffer(10);
//testBuffer=testBuffer.toString();
requestStruct.form[x+'_customBufferFile']= {
value: testBuffer,
options: {
filename: req.files[x].fieldname
}
}
}
request(requestStruct, function(err,res,body){
originalResponse.send(body)
});
});
});
http.createServer(app).listen(3000)
In the python flask server, the .mp4 files are received as a buffer and written to a .mp4 file. However, the .mp4 file is unplayable by ffmpeg "Unknown EBML doctype '(none)'0/0 0_video.mp4: End of file"
from flask import Flask
from flask import request;
app = Flask(__name__);
#app.route('/receiveUpload2', methods=["POST"])
def receiveUpload2():
print("uploaded received....");
numFiles=int(request.args.get("numFiles").encode('ascii', 'ignore'));
print("numFiles",int(numFiles));
for x in range(0,numFiles):
name=request.form.getlist(str(x)+'_customBufferFile[options][filename]');
name=name[0];
print("writing",name);
filebytes=request.form.getlist(str(x)+'_customBufferFile[value]');
filebytes=filebytes[0];
#print(filebytes);
newFileByteArray = bytearray(filebytes,'utf8')
with open("./uploads/"+name,"wb") as output:
output.write(newFileByteArray);
app.run(host="localhost", port=3001);

Upload a file to Nodejs using python request

I got some help here on the nodejs side: Extract file from POST request nodejs
I am new to node, and I am having problems getting this file
node.js (Server PC)
var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer')
var app = express();
var upload = multer({ dest: 'uploads/' })
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
/* POST commands */
app.post('/upload', upload.array(), function (req, res, next) {
console.log("I AM HERE");
})
python script (Client PC)
files = {'file': ('test_file', open(filePath, 'rb'))}
r = requests.post("http://192.168.2.39:3000/upload", files=files)
What am I doing wrong here? thanks
I am getting error 500,
Unexpected fieldError: Unexpected field
at makeError (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\multer\lib\make-error.js:12:13)
at wrappedFileFilter (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\multer\lib\make-middleware.js:114:7)
at emitMany (events.js:127:13)
at Busboy.emit (events.js:201:7)
at Busboy.emit (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\busboy\lib\types\multipart.js:213:13)
at emitOne (events.js:96:13)
at PartStream.emit (events.js:188:7)
at HeaderParser.<anonymous> (C:\qa\Automation\MyProj\Python Automation\Utilities\node\MyProjrtu\node_modules\dicer\lib\Dicer.js:51:16)
in node.js change
upload.array()
to
upload.array('file')
and in python :
files = {'file': ('test_file', open(filePath, 'rb'))} to
files = {'file':open(filepath,'rb')}
check answer from this post Get image sent from post in node.js

Extract file from POST request nodejs

I am trying nodejs for the first time. I am using it with python shell. I am trying to transfer a file from one PC to another using Post request
app.js (Server PC)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/mytestapp', function(req, res) {
console.log(req)
var command = req.body.command;
var parameter = req.body.parameter;
console.log(command + "|" + parameter)
pyshell.send(command + "|" + parameter);
res.send("POST Handler for /create")
});
python file send file from (Client PC)
f = open(filePath, 'rb')
try:
response = requests.post(serverURL, data={'command':'savefile'}, files={os.path.basename(filePath): f})
I use fiddler and the request seems to contain the file on Client PC, but I can't seem to get the file on Server PC. How can I extract and save the file? Is it because I am missing headers? what should I use? thanks
I'm going to guess and say you're using Express based on the syntax in your question. Express doesn't ship with out of the box support for file uploading.
You can use the multer or busboy middleware packages to add multipart upload support.
Its actually pretty easy to do this, here is a sample with multer
const express = require('express')
const bodyParser = require('body-parser')
const multer = require('multer')
const server = express()
const port = process.env.PORT || 1337
// Create a multer upload directory called 'tmp' within your __dirname
const upload = multer({dest: 'tmp'})
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({extended: true}))
// For this route, use the upload.array() middleware function to
// parse the multipart upload and add the files to a req.files array
server.port('/mytestapp', upload.array('files') (req, res) => {
// req.files will now contain an array of files uploaded
console.log(req.files)
})
server.listen(port, () => {
console.log(`Listening on ${port}`)
})

Categories