This question already has an answer here:
Upload image received via Flask to Firebase Storage
(1 answer)
Closed 7 months ago.
I have a flask web page where the user can upload files and on clicking the submit button, they get saved in a folder on my system(called UPLOAD_FOLDER in code).
My goal is to make it happen such that, on clicking the submit button, the chosen files get uploaded to my firebase inside a folder called pos instead of a local folder on my system.
Here's what my app.py currently looks like:
from flask import Flask, render_template, flash, request, redirect
from werkzeug.utils import secure_filename
import os
import urllib.request
import pyrebase
config={
#config stuff
}
app = Flask(__name__)
UPLOAD_FOLDER = r"C:\Users\mihir\settls\PO\POs\fbpdfs"
firebase=pyrebase.initialize_app(config)
storage=firebase.storage()
app.secret_key = "Cairocoders-Ednalan"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['pdf'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def upload_form():
return render_template("upload.html")
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
if __name__ == '__main__':
app.run(debug=True)
Here's what I tried to change in the upload_file() function:
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
path_on_cloud="pos/"+filename
path_local=filename
storage.child(path_on_cloud).put(path_local)
flash('File(s) successfully uploaded')
return redirect('/')
But it doesn't work and is giving me a "No such file or directory error"
Firebase hosting does not have persistent storage by itself. It is common practice to store the file in Cloud Storage. An example can be found here, which saves the file as a temporary file before it is uploaded to Cloud Storage:
import os
import tempfile
import firebase
...
file = request.files['file']
temp = tempfile.NamedTemporaryFile(delete=False)
file.save(temp.name)
firebase.storage().put(temp.name)
# Remove temp file
os.remove(temp.name)
Related
I am trying to use frozen flask, and am running into problems with the URL generator. My app takes a csv file that the user uploads, and will download a modified version to the user's computer.
My question is this: how can I yield a url when the url depends on an uploaded file? I checked the documentation and there is nothing about this. How can I get the filename in my url generator?
Here is the relevant code from my app:
def download_file(name):
cleaning_script.clean(name)
return send_from_directory(app.config["UPLOAD_FOLDER"], 'output.csv')
And here is the url generator
#freezer.register_generator
def download_file():
yield {'name':<What do I put here?>}
if __name__ == '__main__':
freezer.freeze()
Here is a sample of what my webapp looks like.
It's nothing more than a simple upload form, which is handled by this code
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
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 == '':
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(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('download_file', name=filename))
return render_template('index.html')
I started learning Flask by myself today, and while I was toying around with it I made a small program to download a file, and it worked great.
#app.route('/download')
def download():
path = "Path_to_my_file"
return send_file(path, as_attachment=True)
Now I was changing my program a bit and I removed the 'send_file' function and added some other commands. However, when I tried running the program, the download still happened. I have no idea why though.
My Code:
from flask import *
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename
import os
usera = ""
UPLOAD_FOLDER = 'I:/Python'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config ['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///downloads.sqlite3'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String)
download = db.column(db.String)
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
global usera, db
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
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(app.config['UPLOAD_FOLDER'], filename))
db.session.add(User(user = usera, download = filename))
return render_template('lol.html')
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/login',methods = ['POST', 'GET'])
def login():
global db, user
if request.method == 'POST':
usera = request.form['user']
return render_template('lol.html')
#app.route('/download')
def download():
path = "I:/Python/"
users = User.query.all()
return users
if __name__ == '__main__':
app.run(host='0.0.0.0')
I had faced same issue where flask was returning old files (in your case it is still sending files even if code is changed). This issue is due to the fact that file is cached in browser. Clear the browser cache and your api will start working.
I have two python code, the first one is a flask python code(main.py) which collects image from the user and stored it in my local directory, and the second one is tesseract-ocr(ocrDetection.py) python code where the image are getting started to detect text in it.
Now I desired to integrate these two codes, by importing ocr code in flask [ import ocrDetection in main.py]
import os
#import magic
import urllib.request
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def upload_form():
return render_template('upload.html')
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
#app.route('/')
def usemain():
if request.method == 'POST':
import ocrDetection
ocrDetection.mask()
if __name__ == "__main__":
app.run(host='192.168.106.51')
this is not working properly if I give my OCR program after __name__=="__main__" like this
if __name__ == "__main__":
app.run(host='192.168.106.51')
import ocrDetection
it works only when I quit the server (ctrl+c), but I want to start my OCR program simultaniously after giving submit button
This will not work because you have two same routes ('/') which create conflict. I suggest that you create a new route for OCR e.g. '/ocr_detection' or create ocr_detection() as a module in a separate file.
To call OCR module, you can perhaps use it as API endpoint if you want to call from client like browser or as a module to simply call it from your backend (from within the views).
If you call it from within upload_file() module then it will be a sequential call and your browser has to wait until OCR is finished. But to avoid this, you can run periodic script which monitors the UPLOAD_DIR for new files and OCR them. This way your user browsing experience will also be much better.
....
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
ocr_detection(filename)
flash('File(s) successfully uploaded')
return redirect('/')
def ocr_detection(file):
import ocrDetection
ocrDetection.mask()
if __name__ == "__main__":
app.run(host='192.168.106.51')
I have a locally hosted Flask server and a small React application. I'm trying to use FilePond as an easy solution for image uploading. FilePond takes care of sending each image to the server.
So the problem I'm obviously having is with the backend code. I've set up my server like this, per Flask's docs
UPLOAD_FOLDER='/images'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
print(request.files)
if request.method == "POST":
# check if the post request has the file part
if 'file' not in request.files:
print('No file part')
return make_response("No File Part", 400)
file = request.files["file"]
# if user does not select file, browser also submit an empty part
# without filename
if file.filename == '':
print('No selected file')
return make_response("No Selected File", 400)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename) # filenames can be dangerous!
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return make_response("Success", 201)
However, when put a
print(request.files)
statement at the beginning of the upload_file() function, it seems that this is the request the server is receiving:
ImmutableMultiDict([('images', <FileStorage: 'imageName.jpg' ('image/jpeg')>)])
and I have no idea how to deal with that. I don't know if 'images' is where 'file' is supposed to be. I'm just not really sure where to go from here or what to do with the data being received. I don't know what is, I've never seen that <> syntax being used.
Can anyone help?
Here's a pastebin for the whole server-side code
Thank you!
Here's a proof of concept app that lets you upload multiple images using a form:
Note the enctype="multipart/form-data" attribute of the form, without this you cannot upload files.
Also note the multiple attribute of the file input. This allows client to select multiple files. You need to use request.files.getlist() to obtain the list of all uploaded files.
Once you generate the path to save the file, saving a werkzeug.FileStorage object is is just calling its .save(path_to_save) method.
from flask import Flask, request, render_template_string, redirect, abort
from werkzeug import secure_filename
from pathlib import Path
UPLOAD_DIR: Path = Path(__file__).parent / 'uploads'
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
app = Flask(__name__)
def is_valid_upload(upload) -> bool:
# some validation logic
return Path(upload.filename).suffix.lower() in ['.jpg', '.jpeg']
#app.route('/', methods=['GET', 'POST'])
def upload():
html = '''
<form action='/' method='POST' enctype="multipart/form-data">
<input type="file" name='images' multiple>
<button>Upload</button>
</form>
'''
if request.method == 'GET':
return html
uploaded_files = request.files.getlist('images')
if not uploaded_files or not uploaded_files[0].filename:
return redirect('/')
valid_uploads = list(filter(is_valid_upload, uploaded_files))
if not valid_uploads:
return 'invalid image(s)', 400
for upload in valid_uploads:
filename = secure_filename(upload.filename)
save_path = str(UPLOAD_DIR / filename)
upload.save(save_path)
return 'uploaded'
if __name__ == "__main__":
app.run()
I am trying to modify this resume parser https://github.com/bjherger/ResumeParser by creating an API for it. I have used a flask framework to create an API where users can upload pdf/doc files. Here is the code for the flask framework:
UPLOAD_FOLDER = 'user_uploads'
ALLOWED_EXTENSIONS = set(['txt', 'pdf','doc','docx', 'png', 'jpg', 'jpeg',
'gif'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return filename[-3:].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
print type(file)
if file and allowed_file(file.filename):
print "File uploaded successfully. File name is" +file.filename
After getting the user upload, I will then use the textract.process() method from the textract library. However, the 'file' object is a werkzeug.datastructures.FileStorage object which cannot be parsed by textract.
Is there any way to convert the FileStorage object back into pdf/doc, without saving the file to the server, so that textract can parse it ?