My function containing send_file() does not seem to update - python

I am using a Flask application to update some PDF files, convert them to an Excel file and send this file back to the user. I am using an instance folder to store the pdf and the excel files.
But when the user press the button "Download" in order to download the generated Excel file, an old file is downloaded (from an older session).
Moreover, when I try to change my code, for example, I changed the name of this Excel file: I can see the new name in the instance folder, but when I download the file with the webapp, it is still the old name (and old file). I have no idea where the webapp is looking for this old file...
MEDIA_FOLDER = '/media/htmlfi/'
app = Flask(__name__)
app.config.from_object(Config)
INSTANCE_FOLDER = app.instance_path
app.config['UPLOAD_FOLDER'] = INSTANCE_FOLDER+MEDIA_FOLDER
#app.route('/file/')
def send():
folder = app.config['UPLOAD_FOLDER']
try:
return send_file(folder+ "file.xlsx", as_attachment=True)
finally:
os.remove(folder+ "file.xlsx")
<a href="{{ url_for('send') }}" ><button class='btn btn-default'>DOWNLOAD</button></a>
I am really new to webapp in general, thank you for your help :)

send_file takes a cache_timeout parameter which is the number of seconds you want to cache the download. By default is 12 hours.
return send_file(
file.file_path(),
as_attachment=True,
cache_timeout=app.config['FILE_DOWNLOAD_CACHE_TIMEOUT'],
attachment_filename=file.file_name
)
http://flask.pocoo.org/docs/1.0/api/

Related

Download file from google drive using button in html file

I have one file stored in google drive which I download using:
url = 'https://docs.google.com/spreadsheets/d/ID/edit?usp=sharing'
output = 'file.xlsx'
gdown.download(url, output, quiet=False)
My goal is to make that file downloadable in a html file through a button using Google Drive as a backend. Is there any way to do that?
Summarizing:
Some user open an html file where there's a button to download some file placed in my drive.
the flask template I am thinking to use looks like:
from flask import Flask, Response
app = Flask(__name__)
#app.route("/")
def hello():
return '''
<html><body>
Hello. Click me.
</body></html>
'''
#app.route("/getPlotCSV")
def getPlotCSV():
# with open("outputs/Adjacency.csv") as fp:
# csv = fp.read()
excel = '1,2,3\n4,5,6\n'
return Response(
excel,
mimetype="xlsx",
headers={"Content-disposition":
"attachment; filename=file.xlsx"})
EDIT:
I mapped my html button with
"""<form action={url}> <input type=submit value=Go to Google/></form>"""
but it takes me directly to the spreadsheet in google sheets. How do I assign an action to that button so that the file is downloaded locally to the user?

Python htpasswd set zipfiles and delete

I have a flask web app and after a long time run, I want to send an email with a download link to the zip file created and stored after the long time run. The zip file should be htpasswd protected. My ideas up to now:
Create a zip file with the results and store it inside a folder in the flask app root
Question: How to set a htpasswd the zip file?
Sent an email with flask-mail with the link and the password
Delete the zip file after some time
How to check when a file needs to be deleted? My idea was to check with every newly submitted job, delete all jobs older than xy weeks.
with zipfile.ZipFile(memory_file, 'w') as zf:
files = result['files']
for individualFile in files:
data = zipfile.ZipInfo(individualFile['fileName'])
data.date_time = time.localtime(time.time())[:6]
data.compress_type = zipfile.ZIP_DEFLATED
zf.writestr(data, individualFile['fileData'])
memory_file.seek(0)
return send_file(memory_file, attachment_filename='capsule.zip', as_attachment=True)

Read or save a PDF file uploaded to Flask

I'm uploading multiple files to flask using a form, I'm getting the file objects in the flask backend without a problem but the issue is I want to read the PDF files to extract text from them. I can't do it on the file objects I received from the form, another method I thought of was saving the file in the local storage then read them again when I did that using file.save(path, filename) it created an empty text file with the name - filename.pdf
app=Flask(__name__)
#app.route('/')
def index():
return '''
<form method='POST' action='/saveData'>
<input type='file' name='testReport'>
<input type='submit'>
</form>
'''
#app.route('/saveData', methods=['POST'])
def saveData():
if 'testReport' in request.files:
testReport= request.files['testReport']
#This isn't working, a text file is saved with the same name ,ending in pdf
testReport.save(os.path.join(app.config['UPLOAD_FOLDER'], testReport.filename))
return f'<h1>File saved {testReport.filename}</h1>'
else:
return 'Not done'
How do we operate on PDF files after uploading them to flask ?
How do we operate on PDF files after uploading them to flask ?
You should treat them just like normal PDF files - if they were uploaded via Flask application or gathered using other method is irrelevant here. As you
want to read the PDF files to extract text from them.
you should use PDF text-extraction tool, for example pdfminer.six, as this is external module you need to install it first: pip install pdfminer.six
You can directly follow the flask own way as mentioned [here]
This easily works with pdfs. Just don't forget to include your extension in ALLOWED_EXTENSIONS

Download file from root directory using flask

I am generating a xlsx file which I would like to download once it is created. The file is created using a module called 'xlsxwriter'. It saves the file in my root directory, however I cant figure out how to access it via flask, so that it starts a download.
This is how I create the file:
workbook = xlsxwriter.Workbook('images.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write(..someData..)
It saves the file in my root directory.
Now I am trying to access it in order to download it via flask:
app = Flask(__name__, static_url_path='')
#app.route('/download')
def download():
# do some stuff
return Response(
app.send_static_file('images.xlsx'),
mimetype="xlsx",
headers={"Content-disposition":
"attachment; filename=images.xlsx"})
However, I get a 404 Error. Is using send_static_file the correct way to go here?
I found a solution using 'send_file' instead. Providing the path to my file like so:
from flask import send_file
return send_file(pathToMyFile, as_attachment=True)

Flask-strange routing issue

So I am trying to test out serving some user uploaded files in Flask. For images I am simply renaming them with a shortened UUID and putting them in a folder, but for other file types I would like to retain the original filename, so I devised the convoluted method of saving each file in a subfolder named with a UUID. Everything works fine, both the images and files upload and are in the directories they should be in. Just to test I made a template for a download page to just display the filename(planned to implement a download button later). However, when I plug the generated URL in for an uploaded file, I get a 404, and the function that url is supposed to be bound to doesn't even appear to execute(I had it print the filename in console and it doesnt even print), and in console the url is displayed: "GET /xVgePgj2Y HTTP/1.1" 404 -
My code for uploading the files and making the URL:
else:
new_folder_name = shortuuid.uuid()[:9]
os.mkdir(os.path.join(app.config['FILE_FOLDER'], new_folder_name))
file.save(os.path.join(os.path.join(app.config['FILE_FOLDER'], new_folder_name), filename))
new_folder_path = os.path.join(app.config['FILE_FOLDER'], new_folder_name)
return url_for('uploaded_file', new_folder_name=new_folder_name)
My code for serving the files:
#app.route('/<new_folder_name>', methods=['GET'])
def uploaded_file(new_folder_name):
filename = subfolder_fetch(new_folder_name)
return render_template("download.html", filename=filename)
and finally my code for fetching the filename from the subdirectory (called in the serving function - didn't pass the filename to the url_for function because that would make it ugly and complicated):
def subfolder_fetch(new_folder_name):
stuff = os.listdir(os.path.join(app.config['FILE_FOLDER'], new_folder_name))
for name in folder:
print (name)
return name
I'm puzzled as to what is even going on and why my uploaded_file function isn't even being called.
Thanks in advance.

Categories