Upload a file to Nodejs using python request - python

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

Related

How to send file from Nodejs to Flask Python?

Hope you are doing well.
I'm trying to send pdfs file from Nodejs to Flask using Axios.
I read files from a directory (in the form of buffer array) and add them into formData (an npm package) and send an Axios request.
const existingFile = fs.readFileSync(path)
console.log(existingFile)
const formData = new nodeFormData()
formData.append("file", existingFile)
formData.append("fileName", documentData.docuName)
try {
const getFile = await axios.post("http://127.0.0.1:5000/pdf-slicer", formData,
{
headers: {
...formData.getHeaders()
}
})
console.log(getFile)} catch (e) {console.log(e, "getFileError")}
On flask side:
I'm trying to get data from the request.
print(request.files)
if (request.method == "POST"):
file=request.form["file"]
if file:
print(file)
in request.file, I'm getting ImmutableMultiDict([])
but in request.form["file"], I'm getting data something like this:
how can I handle this type of file format or how can I convert this file format to python fileObject.
I solved this issue by updating my Nodejs code.
We need to convert formData file into octet/stream format.
so I did minor change in my formData code :
before: formData.append("file", existingFile)
after: formData.append("file", fs.createReadStream(existingFile)
Note: fs.createReadStream only accepts string or uint8array
without null bytes. we cannot pass the buffer array.

Sending Image from Android with Retrofit and Getting the Image with Python Flask

I am trying to send an image to flask endpoint from android application using retrofit 2 but I seem to fail every time. Flask endpoint is working with both html and postman posts so the problem is on the retrofit part.
Here is the Flask endpoint:
#app.route("/uploadfile", methods=["POST"])
def uploadsingle():
file = request.files['file']
file.save(os.path.join("/home/moralalp/mysite/", file.filename))
return "Success"
Below is the interface for retrofit:
#Multipart
#POST("uploadfile")
Call<ResponseBody> uploadPhoto(#Part("description") RequestBody description, #Part MultipartBody.Part file);
And finally, the uploadFile method:
private void uploadFile(Uri fileUri) {
final EditText name = findViewById(R.id.editText);
RequestBody descriptionPart = RequestBody.create(MultipartBody.FORM, name.getText().toString());
File originalFile = new File(getRealPathFromURI(fileUri));
RequestBody filePart = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), originalFile);
MultipartBody.Part file = MultipartBody.Part.createFormData("file", originalFile.getName(), filePart);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("https://mysite.pythonanywhere.com/")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
UserClient client = retrofit.create(UserClient.class);
Call<ResponseBody> call = client.uploadPhoto(descriptionPart, file);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Toast.makeText(MainActivity.this, "YEAH", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(MainActivity.this, "NOOO", Toast.LENGTH_SHORT).show();
}
});
}
I keep getting "NOOO" Toast message so I can not even get a response, what could be the problem here?
As for this error please use the next line to figure out what is the problem and please edit your question to contain it
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(MainActivity.this, "NOOO", Toast.LENGTH_SHORT).show();
Log.d("Error_TAG", "onFailure: Error: " + t.getMessage());
}
After that Please Filter your log cat to the Error_TAG and Add the Error in the Question
Good Luck
Ok so adding the following in the AndroidManifest.xml file solved my problem:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>

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

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

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

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