If you want to pass the exact file path (aka return report.docx)
Use send_file(exactpath) instead of send_from_directory
Check the documentation here https://flask.palletsprojects.com/en/2.1.x/api/
Answer from Winmari Manzano on Stack OverflowIf you want to pass the exact file path (aka return report.docx)
Use send_file(exactpath) instead of send_from_directory
Check the documentation here https://flask.palletsprojects.com/en/2.1.x/api/
The answer is not possible because of the method flask.send_from_directory(directory, path, filename=None, **kwargs) is required two parameters one is a directory and another one is the path. In official docs from Flask suggest using send_file to Send a file from within a directory. (see more)
Now you can use the method send_file from a flask that provides the exact path with the file name. Below this the example code:
from flask import send_file
@app.route('/download')
def download():
try:
exact_path = r"C:\Users\user\Desktop\upload_foder\report.docx"
return send_file(exact_path, as_attachment=True)
except Exception as e:
return str(e)
python - Unable to retrieve files from send_from_directory() in flask - Stack Overflow
python - Flask: send_from_directory - Stack Overflow
Problem to get a file using send_from_directory in Flask
Using send_file on an entire directory
In production, you don't want to serve static files using the flask server. I suggest you use a proper web server to do that.
For dev, since you don't want to use url_for, you can try to initialize your flask app as below. This way, flask knows where your static files are.
app = Flask(__name__, static_folder='static')
@app.route('/<path:filename>')
def send_file(filename):
return send_from_directory(app.static_folder, filename)
See this post with a lot of info Static files in Flask - robot.txt, sitemap.xml (mod_wsgi)
If you look at the docs for send_from_directory you'll see that it takes the path to the directory in which the files are held on disk. Unless you have your image files saved in a root-level directory named static, you'll want to update your file path:
send_from_directory("/some/path/to/static", "my_image_file.jpg")
That being said, if you are using this for anything that will be under any load, it is better to ensure that your web server serves the files, rather than serving static files from your application.
The problem you are having is that the first generated file has been cached.
Official documentation says that send_from_directory() send a file from a given directory with send_file(). send_file() sets the cache_timeout option.
You must configure this option to disable caching, like this:
return send_from_directory(directory='', filename=filename_csv, as_attachment=True, cache_timeout=0)
@app.route('/download')
def download():
return send_from_directory('static', 'files/cheat_sheet.pdf')
Note: First parameter give it the directory name like static if your file is inside static (the file only could be in the project directory), and for the second parameter write the right path of the file. The file will be automatically downloaded, if the route got download.
I am trying to send a file from a Python/Flask server using
@app.route('/media/<filename>')
def send_foo(filename):
return send_from_directory('/media/usbhdd1/downloads/', filename)but when I click it it stucks and after a time it returns The proxy did not receive a valid response in time.
When the file is a .txt file like file.txt it works perfectly. But for binary files it does not work.
How can I solve it?
Hello! I'm wondering if it is possible to let the user download a directory/folder using send_file. When I try to pass in a directory instead of a file to send_file, I get a permission error in Visual Studio Code.
Edit: Solved! Here's how I did it in case anyone ever has this issue.
If you make the folder into a zip file (using shutil.make_archive for example) then you can pass in the zip file to flask.send_file() and it'll work.
Thank you u/weebsnore for your help!
Hi everyone,
For a project, I architectured my Flask app as a package. So at the root, I'm having a config.py
file where I declare the uploads folder like this:
UPLOAD_FOLDER = 'myapp/uploads'
Now from myapp/routes.py, I manage to upload files in the right folder when creating a post, but then I try to declare a route to retrieve these files with:
@app.route('/uploads/') def upload(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
But when displaying the html page where I call url_for('upload', filename=post.picture) I get a 404 on the image... like if Flask was trying to access /myapp/uploads from /myapp
Does someone have an idea?
I tried to hardcode "uploads" into the first parameter of send_from_directory with success. like this:
@app.route('/uploads/<filename>')
def upload(filename):
return send_from_directory('uploads', filename)
But it's dirty and will break if I ever change the UPLOAD_FOLDER value in config.py. So I'm looking for a clean solution to this.
So I'm messing with a Flask app that uses file uploading and downloading, but I really don't understand the paths.
Here's my project's file structure: https://imgur.com/a/vydd92E
So to save a file, I use file.save(os.path.join("app/UPLOADS", filename))
Which is to say, go into app dir, then into UPLOADS dir.
But to download a file, I use send_from_directory("UPLOADS", filename).
This doesn't make sense to me. One is acting like we're outside of the app directory, the other is acting like we're already in it. How can it be both??
Like both of these lines are in the same file, routes.py, so shouldn't paths to the UPLOADS folder be the same no matter what is being done? And I understand it, the Flask app itself is operating out of the root folder, so I feel like both paths should be app/UPLOADS, but apparently not??? So confused!
routes.py in case you want more context:
from app import app
from flask import render_template, request, redirect, url_for, send_from_directory
from werkzeug.utils import secure_filename
import os
import pdf2image
POPPLER_PATH = "app/poppler-21.10.0/Library/bin"
@app.route("/notmine", methods=["GET", "POST"])
def upload_file():
if request.method == "POST":
print(f"\n\n{len(request.files)}\n\n")
# 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/UPLOADS", filename))
return render_template("upload_file.html")
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in app.config["ALLOWED_EXTENSIONS"]
@app.route("/uploads/<name>")
def download_file(name):
return send_from_directory("UPLOADS", name)So I'm messing with a Flask app that uses file uploading and downloading, but I really don't understand the paths.
Here's my project's file structure: https://imgur.com/a/vydd92E
So to save a file, I use file.save(os.path.join("app/UPLOADS", filename))
Which is to say, go into app dir, then into UPLOADS dir.
But to download a file, I use send_from_directory("UPLOADS", filename).
This doesn't make sense to me. One is acting like we're outside of the app directory, the other is acting like we're already in it. How can it be both??
Like both of these lines are in the same file, routes.py, so shouldn't paths to the UPLOADS folder be the same no matter what is being done? And I understand it, the Flask app itself is operating out of the root folder, so I feel like both paths should be app/UPLOADS, but apparently not??? So confused!
routes.py in case you want more context:
from app import app
from flask import render_template, request, redirect, url_for, send_from_directory
from werkzeug.utils import secure_filename
import os
import pdf2image
POPPLER_PATH = "app/poppler-21.10.0/Library/bin"
@app.route("/notmine", methods=["GET", "POST"])
def upload_file():
if request.method == "POST":
print(f"\n\n{len(request.files)}\n\n")
# 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/UPLOADS", filename))
return render_template("upload_file.html")
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in app.config["ALLOWED_EXTENSIONS"]
@app.route("/uploads/<name>")
def download_file(name):
return send_from_directory("UPLOADS", name)