I want to send an Excel file from UI to Node JS, extract authorization token in NODЕ JS and then send to the Flask Server.
I don’t want to share my authorization token with the client UI, so I don’t want to send the file from there directly to Flask API. Also, I would like not to save the file on Node server-side, like if I send the file with FormData and parse it with formidable on Node server-side.
Something like: Reakt UI => Node.js(attach authorization token) => Flask(server)
My idea is to convert the file to array buffer, send it to Node server, and from there send it with the authorization token to Flask service.
My best approach to the moment is: In my client, I take the file with an input tag, create a buffer, and make a post request to API.
const changeHandler = (event) => { const file = readFile(event.target.files[0]); event.target.value = null; } function readFile(file) { new Response(file).arrayBuffer().then(function(buffer) { handleSubmission(buffer) }); } function handleSubmission(file) { // var blob = new Blob([file], {type: 'application/vnd.openxmlformats- officedocument.spreadsheetml.sheet'}) fetch( '/api/admin/uploadGuestTable', { method: 'POST', body: file } ) .then((response) => response.json()) .then((result) => { console.log('Success:', result); }) .catch((error) => { console.error('Error:', error); }); };
From API endpoint I make post request to Flask:
import auth0 from "../../../assets/utils/auth0"; const fetch = require('node-fetch'); export default auth0.requireAuthentication(async function uploadTable(req, res) { const body = await req.body; var url; if (process.env.DOCKER_ENV === 'development') { url = `http://app:5000/admin/upload/table`; } else { url = `${process.env.NEXT_PUBLIC_API_BASE}/admin/upload/table`; } const response = await fetch(url, { method: "POST", body: body }); res.status(200).json(JSON.stringify("Success")); });
In Flask I receive the binries and want to create pandas dataframe:
@bp.route('upload/table', methods=['POST']) # @requires_auth def upload_guests_table(): data = request.data df = pd.read_excel(data, engine='openpyxl') return jsonify("Success"), 200
I receive this traceback:
Traceback (most recent call last): File "D:projectsbnbvenvlibsite-packagesflaskapp.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "D:projectsbnbvenvlibsite-packagesflaskapp.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "D:projectsbnbvenvlibsite-packagesflask_corsextension.py", line 161, in wrapped_function return cors_after_request(app.make_response(f(*args, **kwargs))) File "D:projectsbnbvenvlibsite-packagesflaskapp.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "D:projectsbnbvenvlibsite-packagesflask_compat.py", line 39, in reraise raise value File "D:projectsbnbvenvlibsite-packagesflaskapp.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "D:projectsbnbvenvlibsite-packagesflaskapp.py", line 1936, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "D:projectsbnbrental_appback_endappadmin.py", line 65, in upload_guests_table df = pd.read_excel(data, engine='openpyxl') File "D:projectsbnbvenvlibsite-packagespandasutil_decorators.py", line 296, in wrapper return func(*args, **kwargs) File "D:projectsbnbvenvlibsite-packagespandasioexcel_base.py", line 304, in read_excel io = ExcelFile(io, engine=engine) File "D:projectsbnbvenvlibsite-packagespandasioexcel_base.py", line 867, in __init__ self._reader = self._engines[engine](self._io) File "D:projectsbnbvenvlibsite-packagespandasioexcel_openpyxl.py", line 480, in __init__ super().__init__(filepath_or_buffer) File "D:projectsbnbvenvlibsite-packagespandasioexcel_base.py", line 355, in __init__ self.book = self.load_workbook(BytesIO(filepath_or_buffer)) File "D:projectsbnbvenvlibsite-packagespandasioexcel_openpyxl.py", line 492, in load_workbook filepath_or_buffer, read_only=True, data_only=True, keep_links=False File "D:projectsbnbvenvlibsite-packagesopenpyxlreaderexcel.py", line 316, in load_workbook data_only, keep_links) File "D:projectsbnbvenvlibsite-packagesopenpyxlreaderexcel.py", line 124, in __init__ self.archive = _validate_archive(fn) File "D:projectsbnbvenvlibsite-packagesopenpyxlreaderexcel.py", line 96, in _validate_archive archive = ZipFile(filename, 'r') File "C:UsersMitkoAppDataLocalProgramsPythonPython37libzipfile.py", line 1258, in __init__ self._RealGetContents() File "C:UsersMitkoAppDataLocalProgramsPythonPython37libzipfile.py", line 1343, in _RealGetContents fp.seek(self.start_dir, 0) ValueError: negative seek value -45960242
I am missing something essential or my approach isn’t correct. Will appreciate any help or guidance. Thanks!
Advertisement
Answer
May be this answer will help? Though it uses Form-Data lib.
Edit
Here example code for express
and flask
// index.js const uploadStream = (file) => { pass = PassThrough() const form = new FormData(); form.append('flask_file_field', pass, file.originalFilename); form.submit('http://localhost:5000/upload', (err, res) => { console.error(err); res.resume(); }); return pass }; app.post('/upload', async (req, res) => { const form = formidable({ fileWriteStreamHandler: uploadStream }); form.parse(req, (err, fields, files) => { res.json('Success!'); }); });
and
# server.py @app.route('/upload', methods=['POST']) def upload_file(): if 'flask_file_field' not in request.files: flash('No file part') return redirect(request.url) file = request.files['flask_file_field'] if file.filename == '': flash('No selected file') return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(UPLOAD_FOLDER, filename)) return f'Uploaded {file.filename}' return 'File is not allowed!'
working code here
Edit2
problem in your code is in express
part. You are expecting to receive files from body, but files are not there