I have a project where I was originally using fetch for all of my requests, and my excel upload function was working fine. I recently made a lot of changes to my application because I added user login and authentication, so I am now trying to reconfigure my routes using async await in React. I am getting different errors that I don't know how to solve. Sometimes when I try to submit the uploaded file I get a 400 error for a bad request, usually saying ""The browser (or proxy) sent a request that this server could not understand.\nKeyError: 'project'". Or I am getting an error on the back-end that says "ValueError: Excel file format cannot be determined, you must specify an engine manually."
I am really confused about where the error is actually occurring because it seems to be reaching the Flask route and then failing.
This is my current request on the front-end:
const onSubmit = async (ev) => {
ev.preventDefault();
let formData = new FormData();
formData.append("project", selectedFile);
// let status = 0;
const data = await api.post("/projects", {
body: formData,
});
if (!data.ok) {
console.log(data);
console.log("error");
} else {
console.log(data);
console.log("uploaded");
}
};
and the back-end route:
@projects.route('/projects', methods=['POST'])
@authenticate(token_auth)
def request_load_pickle_sim():
fn = save_file(None, "project", "xlsx")
print(fn)
request.files["project"].save(fn)
result = process_raw_util_xl_file(fn)
claims = result['claims']
print(claims)
utilities = result['utilities']
weights = result['weights']
maxdiff_scores = result['maxdiff_scores']
data = jsonify(claims)
print(data)
mdp = MaxDiffProject()
mdp.config = MutableDict({
'claims': claims,
'utilities': utilities,
'weights': weights,
'maxdiff_scores': maxdiff_scores
})
print(mdp.config)
db.session.add(mdp)
db.session.commit()
mdp = MaxDiffProject().query.first()
project_config = mdp.config
claims = project_config['claims']
print(claims)
data = jsonify(claims)
return data
My debugger is printing the instance of the file, so it seems like the backend is receiving the file? But after that nothing is working. The file is passed to the process_raw_util_xl_file function (which is where the ValueError error is coming from). I can't figure out what the core issue is because I'm getting conflicting errors. I guess I'm just confused because it was all working fine when I had fetch requests.
The function on the backend is breaking here:
def process_raw_util_xl_file(xl_fn):
# df = pd.read_csv(xl_fn.read())
df = pd.read_excel(xl_fn) # read the excel file
print(df)
row = df.shape[0] # df.shape[0] = Number of rows, df.shape[1] = number of columns
index_col = [col for col in df if 'id' in col.lower()][0]
print(index_col)
df.set_index(index_col, inplace=True) # Setting the ID as the index
# weights = df['Weights'] if 'Weights' in df else pd.Series([1]*row) # Creating the weights array if there are weights , otherwise an array of 1's with # of rows
if 'Weights' not in df:
df['Weights'] = 1
weights = df['Weights']
df.drop('Weights', axis=1, inplace=True)
sum = weights.values.sum() # Sum of the weights
# if 'Weights' in df: df = df.drop('Weights', axis=1) # removing weights from df if they are there
rlh_cols = [col for col in df if 'rlh' in col.lower()][:1]
df = df.drop(rlh_cols, axis=1) # removing RLH from df if they are there
max_diff_scores = (e ** df) / (1 e ** df) * 100 # exp the values of the dataframe with
utils = df
return {
"utilities": utils,
"claims": [col for col in utils],
"maxdiff_scores": max_diff_scores,
"weights": weights
}
CodePudding user response:
You are posting an object
as a body paramter to the server which has a content type as application/json
whereas according the HTTP protocol, to post form-data
the content type must be multipart/form-data
. Here's how you are doing it,
let formData = new FormData();
formData.append("project", selectedFile);
// let status = 0;
const data = await api.post("/projects", {
body: formData,
});
According to the docs (at page end) you must post form data like this,
let formData = new FormData();
formData.append("project", selectedFile);
// let status = 0;
const data = await api.post("/projects", formData);
Also you cannot post body and form data at a same time within single request.