cant send back image from flask server to react server - javascript

So i sent an image from react to flask using an axios post request , the image is in form of a formdata
const response = await axios({
method: "POST",
url: "http://127.0.0.1:5000/upload",
headers: { "content-type": "multipart/form-data" },
data: filou,
in the flask back , i recieve image , store it , then send as a responce another image
#app.route('/upload', methods=['POST'])
#cross_origin()
def fileUpload():
print("hello")
print(request.files)
# check if the post request has the file part
if 'file' not in request.files:
print("no file")
flash('No file part')
return "redirect(request.url)"
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
print("no selected file")
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
print("\n YYYYYYYYYYYYYYYYYYYEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEYYYY \n")
print(file.filename)
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# print(os.path.join(app.config['UPLOAD_FOLDER'], filename))
new_filename = app.config['UPLOAD_FOLDER']
print(new_filename)
return send_file(f"output/final_output/panda.jpg")
when i recieve the image , i get it like this
enter image description here
But i couldnt show it in react and i dunno how to do it (i tried many techniques , blob , createObjectURL ...etc)
.then((response) => {
const data = response.data;
console.log("-----------------------------------------------------");
console.log("I received");
console.log(data);
const img_bytes = new Uint8Array(Buffer.from(response.img, 'hex'));
const blob = new Blob([img_bytes], { type: 'image/jpeg' });
setoutImage(URL.createObjectURL(blob));
// setoutImage(response.data)
setDone(true);
});
{done == true && (
<img
src={outputUrl+outImage}
alt=""
width="400"
/>
)}
if someone can help .

Exactly what Unmitigated said...
axios
.get('your_url',{ responseType: 'blob' })
.then((response) => {
const img = URL.createObjectURL(response.data);
setoutImage(img);
...
});

Related

Request.files returns empty

I'm trying to send a wav file from my HTML page to my flask back-end. I've looked at similar issues which say to add the name=file tag to the form attribute and also enctype=multipart/form-data but I still do not receive the file in the backend. Request.files contains an empty ImmutableMultiDict([]) I've also tried adding audio/wav
<html>
<form method="post" enctype="multipart/form-data">
<div>
<label>Select file to upload</label>
<input type="file" id="fileinput" name="file">
</div>
<button type="submit" value=Upload>Convert</button>
</form>
<script>
// Select your input type file and store it in a variable
const input = document.getElementById('fileinput');
// This will upload the file after having read it
const upload = (file) => {
var prod = 'https://elementa-backend-staging.herokuapp.com/wrapper/v1/file';
var debug = 'http://127.0.0.1:5000/wrapper/v1/file';
console.log("Sending file: " + file);
fetch(debug, { // Your POST endpoint
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body: file // This is your file object
}).then(
response => console.log(response.json()) // if the response is a JSON object
).then(
success => console.log("Test succeeded: " + success) // Handle the success response object
).catch(
error => console.log("Test failed: " + error) // Handle the error response object
);
console.log(file[0]);
};
// Event handler executed when a file is selected
const onSelectFile = () => upload(input.files);
// Add a listener on your input
// It will be triggered when a file will be selected
input.addEventListener('change', onSelectFile, false);
</script>
</html>
Back-end:
from flask import Flask, request, abort, jsonify
import speech2new # this will be your file name; minus the `.py`
from flask_cors import CORS, cross_origin
wrapper = Flask(__name__)
cors = CORS(wrapper)
UPLOAD_FOLDER = '/uploads'
wrapper.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
ALLOWED_EXTENSIONS = {'wav', 'png', 'jpeg'}
#wrapper.route('/wrapper/v1/file', methods=['POST'])
def mozdhe():
#Pass the request parameters (containing the .WAV file) to the Speech-to-Text
return jsonify(speech2new.get_file(request))
if __name__ == '__main__':
wrapper.run(host='127.0.0.1', port='5000', debug=True)
#speech2new.py get_file function
def get_file(request):
#Outlier case: No file
print(request.files)
if 'file' not in request.files:
return json.dumps("You did not send a file ")
file = request.files['file']
#Outlier case: Invalid filename (not parse-able)
if file.filename == "":
return json.dumps("The application didn't assign a filename.")
#Ideal case: Audio file recieved in Byte Form, pass to Mozhde's Library
file.save('recievedAudio')
predict = dict({'result':get_large_audio_transcription(file)})
#data = json.dumps(predict)
return predict
To make a multipart/form-data file upload via fetch you have to use a FormData object as the data parameter you're using a file list
// This will upload the file after having read it
const upload = (file) => {
var prod = 'https://elementa-backend-staging.herokuapp.com/wrapper/v1/file';
var debug = 'http://127.0.0.1:5000/wrapper/v1/file';
var formData = new FormData();
// Add file to formdata object
formData.append("file", file); // Use "file" as thats what the server expects
console.log("Sending file: " + file);
fetch(debug, { // Your POST endpoint
method: 'POST',
body: formData// This is your form data object
}).then(
response => console.log(response.json()) // if the response is a JSON object
).then(
success => console.log("Test succeeded: " + success) // Handle the success response object
).catch(
error => console.log("Test failed: " + error) // Handle the error response object
);
console.log(file);
};
// Event handler executed when a file is selected
const onSelectFile = () => upload(input.files[0]); // send the file

How to download remote image then upload image as an image file for form submission?

There are similar questions like this, this, this, and this, but none help.
In Node, the goal is to use the axios module to download an image from Twitter then upload this image as an image file as part of a form submission.
This code downloads the Twitter image, but the uploaded binary image is corrupted when it reaches the server (also our server).
The image must be uploaded in binary.
A form is required because other fields are also submitted with the binary image. These other form fields were removed to simplify the code sample.
const axios = require('axios');
const FormData = require('form-data');
let response = await axios.get('https://pbs.twimg.com/media/EyGoZkzVoAEpgp9.png', {
responseType: 'arraybuffer'
});
let imageBuffer = Buffer.from(response.data, 'binary');
let formData = new FormData();
formData.append('image', imageBuffer);
try {
let response = await axios({
method: 'post',
url: serverUrl,
data: formData,
});
// Do stuff with response.data
} catch (error) {
console.log(error)
}
You should pass the headers to the axios call using formData.getHeaders() to send a Content-Type header of multipart/form-data. Without it, a Content-Type header of application/x-www-form-urlencoded is sent. You could pass a responseType of stream to the axios call that downloads the image and add the stream to the form data.
You can also use axios.post to simplify the method call.
const url = 'https://pbs.twimg.com/media/EyGoZkzVoAEpgp9.png'
const { data: stream } = await axios.get(url, {
responseType: 'stream',
})
const formData = new FormData()
formData.append('image', stream)
try {
const { data } = await axios.post('http://httpbin.org/post', formData, {
headers: formData.getHeaders(),
})
console.log(data)
} catch (error) {
// handle error
}
You can use the fetch API to fetch the image as a blob object and append it to form data. Then simply upload it to its destination using Axios, ajax, or the fetch API:
const mediaUrl = "https://pbs.twimg.com/media/EyGoZkzVoAEpgp9.png"
fetch(mediaUrl)
.then((response) => response.blob())
.then((blob) => {
// you can also check the mime type before uploading to your server
if (!['image/jpeg', 'image/gif', 'image/png'].includes(blob?.type)) {
throw new Error('Invalid image');
}
// append to form data
const formData = new FormData();
formData.append('image', blob);
// upload file to server
uploadFile(formData);
})
.catch((error) => {
console.log('Invalid image')
});

Getting PDF from Json API response

I have a problem with the PDF file I get from the API in response to a Json GET request.
It does get a good string in Json, however, which makes the PDF file that appears corrupted. I tried to convert the response to a string but it didn't do anything.
Here is my code:
getPDF() {
axios
.get(apiurl + "api/Dok", { params: { }, headers: { } })
.then(response => {
const res = response.data.fileData;
const pdfcode = res.toString();
this.convertPDF(pdfcode)
}
)
.catch(error => {
alert('error')
});
}
convertPDF(value) {
const file = new Blob(
[value],
{type: 'application/pdf'});
const fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
So if i'm import the pdf file from local and add it to this function istead of url in console i'm getting long string response
JVBERi0xLjUNCjQgMCBvYmoNCjw8L1R5cGUgL1BhZ2UvUGFyZW50IDMgMCBSL0NvbnRlbnRzIDUgMCBSL01lZGlhQ...
and PDF works, but when get it from URL i'm getting :
{"fileData":"JVBERi0xLjUNCjQgMCBvYmoNCjw8L1R5cGUgL1BhZ2UvUGFyZW50...
I checked it in notepad, the first answer and the content of "" are identical
any ideas what i can do?

How to recieve formdata in django backend

I want to send the recorded wecam video to django backend, But can't figure out how to generate the video in backend.
function sendVideoToAPI () {
const url = '/upload/'
let blob = new Blob(chunks, {type: media.type });
let fd = new FormData();
let file = new File([blob], 'recording');
fd.append('data', file);
fetch(url1, {
method: 'POST',
body: fd
})
.then(res => console.log(res))
.catch(err => console.log(err))
}
In django views how to generate the video
.Is there any way to do it..?
EDIT
Views.py
def upload(request):
if request.method == 'POST':
request.FILES.get('data') as f:
print(f.size)
print(type(f))
return redirect("/")
while running server it gives The following error
Error
request.FILES.get('data') as f:
^
SyntaxError: invalid syntax
in django's view you can access to your files through request like this:
request.FILES.get('data') as f:
# your code
NOTE: this will make you a 'TemporaryUploadedFile' which means that after working with that, it destroys automatically

how to attach a file to request so that it shows up as request.files in python

The way I have found examples are:
const file = fs.readFileSync(filePath)
const formData = new FormData()
formData.append('userId', userId)
formData.append('file', file)
const options = {
method: 'post',
url: 'http://localhost:5000/uploadFile',
headers: {
'content-type': 'multipart/form-data'
},
data: formData
}
await axios(options).then(res => { console.log(res) }).catch(err => { console.log(err) })
But this doesn't attach the file in request.files which is required for python. Since it doesn't attach it as file, the information about file type is also lost.
I have also tried using the following. It does attach the file to request.files but the contents are not of the proper file and all I get is a text string which assumingely is a buffer string output.
const file = new File(fs.readFileSync(filePath), fileName, { type: 'text/csv' })
The aim is to preserve the file type information so that server can save the file properly. What am I missing?
Note that the requests are not sent from nodejs (which has file access) directly.

Categories