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.
Related
I'm trying to upload a file from a React component using Apollo GraphQL's rest link ( which allows us to call REST APIs inside GraphQL queries). I'm able to send the file from the client to the server using FormData in the bodySerializer option of the query, but I'm unable to extract the file on the server side. I'm using tornado on the server btw.
My graphql query looks like this:
const UPLOAD_AVATAR = gql`
mutation UploadAvatar($serialNumber: String!, $file: File!) {
profile(serialNumber: $serialNumber, file: $file)
#rest(
method: "POST"
path: "/v2/profile/avatar-upload?serial_number={args.serialNumber}"
bodyKey: "file"
bodySerializer: $bodySerializer
) {
data
}
}
`;
const [uploadAvatar, { loading: uploadLoading }] = useMutation(
UPLOAD_AVATAR,
{
onCompleted: () => {
setIsEditMode(false);
refetch();
},
}
);
When calling the uploadAvatar function, I'm passing in a bodySerializer variable, which creates a new FormData object inside, appends the file to it, and returns the result along with the headers:
and I'm using FormData to add the file to the query like this:
function handleUploadFile(selectedFile) {
uploadAvatar({
variables: {
serialNumber: serialNumber,
file: selectedFile,
bodySerializer: (data: any, headers: Headers) => {
const formData = new FormData();
formData.append("file", data);
return { body: formData, headers };
},
},
});
}
On the server side, I first tried to look for the file inside self.request.files, but found nothing there. The file is actually inside self.request.body, but I'm not sure how to extract it.
#gen.coroutine
#tornado.web.authenticated
def post(self):
target_file = self.request.body
print(target_file)
This is what self.request.body looks like:
b'------WebKitFormBoundaryiE73JY38ydKyAVYU\r\nContent-Disposition: form-data; name="file"; filename="Screenshot 2022-12-16 at 22.31.07.png"\r\nContent-Type: image/png\r\n\r\n\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x96\x00\x00\x01j\x08\x06\x00\x00 ... 0\x00\x00IEND\xaeB\x82\r\n------WebKitFormBoundaryiE73JY38ydKyAVYU--\r\n'
I tried to decode the file
decoded_file = json.loads(target_file.decode("utf-8"))
but got an error: 'utf-8' codec can't decode byte 0x89 in position 164: invalid start byte.
How do I correctly extract the file from self.request.body?
Appreciate the help!
Hi i got a python fast api backend server.
#app.get("/getName")
async def getName() -> JSONResponse:
data_sniffer = DataSniffer()
data = json.dumps(data_sniffer.get_data())
print(data)
return JSONResponse(content=data,headers={'content-type':'application/json'})
this is the console output of data :{"first_name": "test"}
My Frontend Code looks like this
useEffect(() => {
async function query() {
const options = {
method: 'GET',
mode: 'no-cors',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application-json',
},
};
const res = await fetch('http://127.0.0.1:3000/getName', options);
console.log(res);
const data = await res.json();
console.log(data);
}
query();
});
but i get following error message SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
my network response looks like this:
"{"first_name": "test"}"
Has anyone a clue why fetch cant parse the json?
For anyone who has the same issue what worked for me is I moved my Backend folder to the root directory of my Frontend and removed the mode no-cors of the fetch request. I installed the no cors app and now it works. I think the mode no-cors broke my request.
I am using angular as the front-end scope and Django Rest as the back-end. Now I am facing a situation where I want to create a Model. The structure of a model is really complex in nature, I could use some other simple way outs but using JSON and passing the files with that can really simplify the logic and also make process really efficient.
I am have been trying a lot but none of the ways seem to work.
Can some someone help me with a standard way or tell me even it is possible or not.
This the structure of my Typescript which I want to upload.
import { v4 as uuid4 } from 'uuid';
export interface CompleteReport{
title: string;
description: string;
author: string;
article_upload_images: Array<uuid4>,
presentation_upload_images: Array<uuid4>,
report_article: ReportArticle,
report_image: ReportImage,
report_podcast: ReportPodcast,
report_presentation: ReportPresentation,
report_video: ReportVideo,
}
export interface ReportArticle{
file: File;
body: string;
}
export interface ReportPodcast{
file: any;
}
export interface ReportVideo{
file: Array<File>;
}
export interface ReportImage{
file: File;
body: string;
}
export interface ReportPresentation{
body: string;
}
export interface UploadImage{
file: File;
}
I don't see how you wanna send data, but if you wanna send data with multipart/data-form, I think you should make small changes to your report structure.
JSON doesn't supports binary. So, you can't put files on it. You need to split file and report JSON.
(async () => {
let formData = new FormData();
// here's how to send file on multipart/data-form via fetch
let reportFile = document.querySelector('#file');
formData.append("file", imagefile.files[0]);
// here's your report json
let report = {
...
};
formData.append("report", JSON.stringify(report));
// send request and upload
let response = await fetch(url, {
method: 'POST',
body: formData
});
// do something with response
let responseText = await response.text();
console.log(responseText)
})();
And I see UUID on your frontend code, I think it's better to put that kinda stuff on backend to prevent manipulated request. I think it's better to put complicated stuff, and any server data related on your backend. Just my opinion.
I have created a react app that takes information from a react frontend, sends it to a flask backend with axios, which then processes the information and creates a new image. Im trying to get flask to send the image via send_file to react, but i'm not sure how to do it. I tried saving the image as a png, and then sending it, but the react side can't use that since it's encoded.
Here's what's going on:
flask:
img = Image.fromarray((np.uint8(cm(img)*255)))
img.save("./thenewimg.png")
return send_file('./thenewimg.png','image/png')
react:
class App extends React.component{
onReturnProcessed = res =>{
console.log(res.data)
this.setState({img:res.data})
this.setState({ImgReturned:true})
console.log(res.data.img)
}
return axios
.post(`http://localhost:5000/time`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(res => {
this.onReturnProcessed(res);
return res
});
}
render(){
return(
<div>
{this.state.ImgReturned &&
<img src={(this.state.img)} />}
</div>
);
}
}
React then sets the state variable "img" to whatever flask returns (namely, the file that flask sends to it). I try to display this state variable in an image html line, but it doesn't let me. Any ideas on how to do this?
note:
neither of these is the full code, but I think they give most of what is needed to get an idea of what is done.
Heres some of what is printed in console when the "img" state variable is logged: �m�O<���+����� ��S����i�<��G�~qZrޱ�����s�~9���
You're passing a second positional argument to send_file which it doesn't accept.
I think you're looking for:
return send_file('./thenewimg.png', mimetype='image/png')
However, as you're passing a filename as the first argument it should automatically detect the mimetype, based on that .png extension, so you'd probably get away with just:
return send_file('./thenewimg.png')
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}`)
})