At Server end I use Python flask:
from flask import Flask, request
app = Flask(__name__)
#app.route("/upload", methods=["POST"])
def upload():
print request.files
print request.form
return "200 ok"
if __name__ == '__main__':
app.run(port=5000)
Java test code block:
public void test_Upload() throws Exception{
MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
MediaType MEDIA_TYPE_XO = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("/Users/lollipop/Downloads/ic_launch.png")))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"google\""),
RequestBody.create(MEDIA_TYPE_XO, new File("/Users/lollipop/Downloads/google-logo.png")))
.build();
Request request = new Request.Builder()
.url("http://localhost:5000/upload")
.post(requestBody)
.build();
Response resp = httpClient.newCall(request).execute();
System.out.println(resp.body().string());
}
And I run the test. server end cannot read the file from request.forms
output on server:
ImmutableMultiDict([])
ImmutableMultiDict([('image', u'5 ...many data ... fffd'), ('google', u'5i\u ...many data ... fffd'),('title', u'Square Logo')])
Why my files upload to request.form not in request.files. And all binary file data is parsed to unicode string.
Next, I test in Python requests. follows codes:
resp = requests.post("http://localhost:5000/upload",
files={
"image": open("/Users/lollipop/Downloads/ic_launch.png", "rb"),
"title": open("/Users/lollipop/Downloads/ic_launch.png", "rb"),
"google": open("/Users/lollipop/Downloads/google-logo.png", "rb")
})
And the server end output is reversed:
ImmutableMultiDict([('image', <FileStorage: u'ic_launch.png' (None)>), ('google', <FileStorage: u'google-logo.png' (None)>), ('title', <FileStorage: u'ic_launch.png' (None)>)])
ImmutableMultiDict([])
the upload files are in request.files not in request.form, this is my expected result.
So. how can I use OkHttp to upload files to flask server, and use request.files to retrive.
Update
the request is Flask requst.
from flask import request
the requests is a Python http client library.
This bug is not to Flask. I get misguided by this answer
At the OkHttp recipe in the documents. Described the post a file use the following code
public static final MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
File file = new File("README.md");
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
Actually, this manner is not error, it post a file you don't need to provide a filename and other form data.
But this is not a usual usage.
We often need to upload a file with specified name and some key-value form data. We even need to upload more than one file.
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("username", username)
.addFormDataPart("password", password)
.addFormDataPart("avatar", "avatar.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.addFormDataPart("introduce_image", "introduce_image.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.build();
Related
This question already has answers here:
Get the data received in a Flask request
(23 answers)
Closed 4 months ago.
i am trying to upload a form data in js into my flask server but i am not getting file in the server.
My code in JS is:
const form = document.forms.namedItem('fileinfo')
form.addEventListener('submit', async (event) => {
event.preventDefault()
let formData = new FormData(form)
formData.append('firstName', 'John')
let file1 = document.getElementById('fileInput').files[0]
console.log(formData)
let response = await fetch('http://127.0.0.1:5000/stateUpload', {
method: 'POST',
body: formData,
})
let _response = await response.json()
})
and this is my flask code:
#app.route("/stateUpload", methods=[ "POST"])
def stateUpload():
_data = request.form.to_dict(flat=False)
print("this is form data")
print(_data)
return "JSON File successfully uploaded"
This is my output in console in server when i press submit button:
this is form data
{'firstName': ['John']}
and this is my output in front end:
i am not able to get this file in the flask
In contrast to normal form fields, which can be accessed via request.form, it is necessary to use request.files on the server side in order to receive transmitted files. Here you can request an object of type FileStorage using the name of the form field.
#app.route("/stateUpload", methods=[ "POST"])
def stateUpload():
_data = request.form.to_dict(flat=False)
print("this is form data")
print(_data)
file = request.files.get('file')
print(file)
return "JSON File successfully uploaded"
The documentation for uploading files can be found here.
I have a NestJS api (uses express) that gets a file (pdf or image) and sends it to a Flask api to further analize.
When sent through Postman, the files are available in Flask through request.files but I've found no way to not send it to request.form when sending it from the node server:
formData.append(
"file",
file.buffer,
)
formData.append(
"filename",
file.originalname
)
const res = await fetch('http://flask_api', {
method: 'POST',
body: formData.getBuffer(),
headers: formData.getHeaders()
});
Then in the Flask api, the value is available through: request.form["file"] but it is a str and therefore can't be used as a file to be saved, etc.
Will somehow sending files to request.files in Flask from Node fix this? If so, can this be done all from memory i.e. not saving a temp file when I get it in the Node server?
Thank you!
From Salesforce File, I want to read the file and get the content between some text and store it in the Custom object record field.
For this, I have created an external API(python script deployed to heroku) where I am sending the file content as blob(basically the content of the file is Blob in Salesforce
).
Now I want to read the file and get the text. But I was not able to read the blob data.
If I convert the blob to string in SF while posting and decode it in python also doesn't work. Please give some inputs on this. I am new to python.
my python code :
from flask import Flask, request, jsonify
import base64
import blob
app = Flask(__name__)
#app.route('/get/record/', methods=['GET', 'POST','DELETE', 'PATCH'])
def index():
if request.method == 'POST':
print("===inside===")
payload_list = request.get_json(force=True)
print("====next line payload_list ===")
print(blob(payload_list["BlobData"])
# responseStr = str(payload_list["BlobData"])
# print("===decodedata===")
# print(base64.b64decode(responseStr))
return "sucesss"
Salesforce Rest Code:
List<ContentVersion> cv = [SELECT ContentDocumentId,VersionData from ContentVersion
where ContentDocumentId = 'xxxxxxxxxx' order by CreatedDate DESC];
String bodyEncoded = EncodingUtil.base64Encode(cv[0].versiondata);
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://realpyth.herokuapp.com/get/fileService/');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
request.setBody('{"BlobData":"'+cv[0].versiondata+'"}'); // Send the data as Blob
//request.setBody('{"BlobData":"'+bodyEncoded+'"}'); // Convert the blob data and send as String
HttpResponse response = http.send(request);
if (response.getStatusCode() != 201) {
System.debug('=======' +response.getStatusCode() + ' ' + response.getBody());
} else {
System.debug('====response==='+response.getBody());
}
I want to test a view that is suppose to receive files attached with the request.
my django test:
TEST_DIR = "myapp/tests/test_data/"
file_name = "some_resume.pdf"
email_data = {
"sender": "somedude#someprovidercom",
"recipient": "someotherdude#someotherprovider.com",
"subject": "New candidate",
"stripped-html": "Check out this new candidate."
}
api = APIClient()
with open(FILE_DIR + file_name, "rb") as fp:
response = api.post(
"/api/v1.0/emails/receive/",
data=email_data,
files={"resume": fp}, # pass file handler open with byte mode
format="multipart", # use multipart format
)
print(response)
# test some stuff
the api response is correct: <Response status_code=200, "application/json">
but when I print the files attached to the request in the View I get nothing:
print(request.FILES)
# <MultiValueDict: {}>
I checked everywhere and the format for my api request looks file.
Also, my view works fine when I test with shell sending request with with python requests library.
Am I missing anything? Could id be somehow related to my test environment or some obscure middlewares?
I'm running a simple Flask backend that will process HTTP requests with audio files and read the data. Eventually I will like to read the data and have an ML model perform an inference with the audio data, but the first step is to simply read the data in the proper encoding format.
My code for the Flask app is below:
#app.route('/api/audio', methods=['GET', 'POST'])
def get_score():
if request.method == 'POST':
length = request.content_length
content_type = request.content_type
data = request.data
return f"""Content Type is {content_type} and data is {data} \n length is {length}"""
elif request.method == 'GET':
return 'get method received'
My test code on the client side generating the POST request is below:
def send_audio():
#print('attempting to send audio')
url = 'http://127.0.0.1:5000/api/audio'
with open('/Users/kaushikandra/laughter-detection/LaughDetection/crowd_laugh_1.wav', 'rb') as file:
data = {'uuid':'-jx-1', 'alarmType':1, 'timeDuration':10}
files = {'messageFile': file}
req = requests.post(url, files=files, json=data)
print(req.status_code)
print(req.text)
I get the following output from the server when I run the client script.
200
Content Type is multipart/form-data; boundary=d95c72e01bdfac029b16da2b8f144cbd and data is b''
length is 129722
I can see from the 200 status code that the flask app is correctly receiving the POST request, but when I try to read the data I get an empty b'' string. What is the proper method to use to decode the audio file? or is the problem with the way I'm sending the POST request in the client script?
I've looked at other questions on StackOverflow and they have mentioned to send the file as a part of the 'files' parameter in the POST request.
Try using request.files to get your audio file:
#app.route('/api/audio', methods=['GET', 'POST'])
def get_score():
if request.method == 'POST':
request.files['messageFile']
Also request.data is just an empty string if I recall. Use request.json() or request.get_json(force=True).
For those, who wants to save and process .wav or any files, you may use FileStorage.save.
main.py (Flask)
#app.route('/predict_with_db', methods=['POST'])
def predictWithDb():
if request.method == 'POST':
save_path = os.path.join(dirname, "temp.wav")
request.files['music_file'].save(save_path)
#continue processing...
index.html
<input id="music_file" name="music_file" type="file" accept=".mp3,.wav" class="hidden" />
form.js
var formData = new FormData();
const fp1 = $('#music_file').prop('files')[0];
formData.append('music_file', fp1, fp1.name);
$.ajax({
type: "POST",
url: "/predict",
data: formData,
processData: false,
contentType: false,
success: (result) => {
console.log(result);
},
error: (err) => {
console.log(err);
}
});