This question already has answers here:
Refering to a directory in a Flask app doesn't work unless the path is absolute
(1 answer)
Saving upload in Flask only saves to project root
(1 answer)
Flask: IOError when saving uploaded files
(2 answers)
Closed 4 years ago.
I've looked at a couple of the other questions but can't figure out what is going wrong. I get the following error: "FileNotFoundError: [Errno 2] No such file or directory: '/uploads\MRRtest.csv'" Can anyone help? What is the difference between the forward and backward slashes on the error message?
Thanks
from flask import Flask, render_template, request, redirect, url_for, flash
from flask.ext.bootstrap import Bootstrap
from werkzeug import secure_filename
import os
app = Flask(__name__)
bootstrap = Bootstrap(app)
UPLOAD_FOLDER = '/uploads'
ALLOWED_EXTENSIONS = set(['csv'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
file = request.files['file']
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('uploaded_file', filename=filename))
return render_template('index.html')
My index.html template is as follows:
{% extends "base.html" %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Upload File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
</div>
{% endblock %}
/uploads means an absolute link (C:/upload), so you should use upload/ instead.
Also, you can use the nice snippet from https://stackoverflow.com/a/20257725/5851179
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = os.path.join(APP_ROOT, 'static/uploads')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Just realized from the comments that my uploads directory is in the same directory as my run.py file rather than the 'templates' directory that index.html is running from. I modified the
UPLOAD_FOLDER = '/uploads'
to
UPLOAD_FOLDER = './uploads'
I'll now work on building the "url for endpoint"
Thanks for your help.
Related
I am making a webapp for OCR on document with layoutlm using flask, website has upload system that accepts images and documents which are later processed by a python file for OCR which returns a JSON containing 'key' as field name like 'Name', 'DOB' and value as corresponding answer to the field as 'Akshit', '17/02/2002'. I have got the upload system working but am not able to figure out how I display these values into my HTML webpage. Can you please help?
app.py:-
from flask import Flask
UPLOAD_FOLDER = r'path\to\upload\folder'
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
main.py :-
#import magic
import urllib.request
from invoice_docquery import ret_scores
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = set(['pdf', '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('index.html')
#app.route('/', methods=['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 file.filename == '':
flash('No file selected for uploading')
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))
json_ans = ret_scores(filename) # Performs OCR and returns json containing key as field names and value as its corresponding answers
flash('File successfully uploaded')
return redirect('/')
else:
flash('Allowed file types are pdf, png, jpg, jpeg')
return redirect(request.url)
if __name__ == "__main__":
app.run()
HTML code so far (index.html):-
<!doctype html>
<title>Python Flask File Upload Example</title>
<h2>Select a file to upload</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="file" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
function 'ret_scores' in main.py returns the required json for which I want to display its values in the HTML webpage
Do let me know if any additional information is required
It's difficult to diagnose exactly what your issue is as you didn't explain what output you're getting (error message? no content showing?), but the issue appears to be in the way you're trying to use the jinja template, in particular in the line:
{% with messages = get_flashed_messages() %}
What is get_flashed_messages() and how does the template know where to find it?
You pass information to templates as parameters in render_template, so your #app.route('/') will need to contain a line like:
return render_template('index.html', messages)
Passing variables between routes gets messy and confusing, so I recommend using session variables to store the information that you will pass to the template.
I've rewritten your code to demonstrate the basic flow, but please don't expect it to run first time as I haven't run it to test. There may still be some debugging to do but hopefully it should demonstrate the general idea and get you moving in the right direction.
app.py looks fine as-is.
main.py:
#import magic
import urllib.request
from invoice_docquery import ret_scores
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = set(['pdf', 'png', 'jpg', 'jpeg'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def upload_form():
if session['messages']:
return render_template('index.html', messages=session['messages'])
else:
return render_template('index.html', messages={})
#app.route('/', methods=['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 file.filename == '':
flash('No file selected for uploading')
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))
session['messages'] = ret_scores(filename) # Performs OCR and returns json containing key as field names and value as its corresponding answers
flash('File successfully uploaded')
return redirect('/')
else:
flash('Allowed file types are pdf, png, jpg, jpeg')
return redirect(request.url)
if __name__ == "__main__":
app.run()
index.html:
<!doctype html>
<title>Python Flask File Upload Example</title>
<h2>Select a file to upload</h2>
<p>
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="file" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
Feel free to ask any question is in the comments and I'll do my best to help when I can.
From my flask app, I need to access the file from the <input type="file">. Whether it be the file data or the actual file. I need to do something like this: http://jsfiddle.net/ugPDx/ but without js
thanks in advance!
Make sure you have created the static folder and inside that folder, you have the uploads folder.
upload.html
<!doctype html>
<title>Python Flask Image Upload and Display Example</title>
<h2>Select an image to upload and display</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
{% if filename %}
<div>
<img src="{{ url_for('display_image', filename=filename) }}">
</div>
{% endif %}
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="file" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
app.py
import os
import urllib.request
from flask import Flask, flash, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = 'static/uploads/'
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
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_image():
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No image selected for uploading')
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))
#print('upload_image filename: ' + filename)
flash('Image successfully uploaded and displayed')
return render_template('upload.html', filename=filename)
else:
flash('Allowed image types are -> png, jpg, jpeg, gif')
return redirect(request.url)
#app.route('/display/<filename>')
def display_image(filename):
#print('display_image filename: ' + filename)
return redirect(url_for('static', filename='uploads/' + filename), code=301)
if __name__ == "__main__":
app.run()
My site will enable users to post something like a blog post, but with a audio file attached to it, so that other user can listen to it while reading. I made a dummy post so that I could check a few things and also a simple route.
from flask import render_template
from site import app
posts = [{
'title': 'asdf',
'text': 'asdf',
'file': "2.mp3"
}]
#app.route("/")
#app.route("/home")
def home():
return render_template('home.html', posts=posts)
I also have the home.html template
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
</head>
<body>
{% for post in posts %}
<h1>
{{ post.title }}
</h1>
<h2>
{{ post.text }}
</h2>
<audio controls>
<source src="{{ post.file }}" type="audio/mpeg">
</audio>
{% endfor %}
</body>
</html>
My logic was simple: if the 2.mp3 file is in the same directory as the home.html file, then the music should play. But it doesn't. I don't really have an idea what should I do. I'm using Python 3.7.
This is actually a bit more complex than that because they're is two options.
The first is the "easy one" and what's you're trying to achieve. Having the file in the static folder along with the home template and return it to the user via the template.
To achieve that, you just need to modify your template a bit:
<source src="{{ url_for('static', filename=post.file) }}" type="audio/mpeg">
However, that will not work if the file is not in your static folder (i.e. if the user uploads the file himself).
For that, you will need to follow the steps in the docs and you will probably end up to something close to the following:
import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
from flask import send_from_directory
UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', '.mp3'}
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():
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))
return redirect(url_for('uploaded_file',
filename=filename))
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('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
I'm new in Flask, I want to take single file that have been uploaded in my upload path. Then i want to read and send it to my html after hr tag. How can i do that?
This is My Code:
import os
from flask import Flask, render_template, request, redirect, url_for, abort, \
send_from_directory
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['UPLOAD_EXTENSIONS'] = ['.txt', '.doc']
app.config['UPLOAD_PATH'] = 'uploads'
#app.route('/')
def home():
files = os.listdir(app.config['UPLOAD_PATH'])
return render_template('home.html', content=files)
#app.route('/', methods=['POST'])
def upload_file():
uploaded_file = request.files['file']
filename = secure_filename(uploaded_file.filename)
if filename != '':
file_ext = os.path.splitext(filename)[1]
if file_ext not in app.config['UPLOAD_EXTENSIONS']:
abort(400)
uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
return redirect(url_for('home'))
if __name__ == "__main__":
app.run()
And This one is my HTML Page:
<!doctype html>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<h1>File Upload</h1>
<form method="POST" action="" enctype="multipart/form-data">
<p><input type="file" name="file"></p>
<p><input type="submit" value="Submit"></p>
</form>
<hr>
{{ content }}
</body>
</html>
It saves the data, but I can't access the data since I use this codefiles = os.listdir(app.config['UPLOAD_PATH'])
You need a variable route that will accept the a filename like #app.route('/<filename:filename>').
You then need to get the file with that name from your upload directory like file_path = os.path.join('UPLOAD_PATH', filename).
Then you need to read the contents of that file and pass it into your view.
with open(file_path) as file:
content = file.read()
Then you can access it in your HTML file and display it.
<p>{{ content }}</p>
Here is a complete example of the route I described:
#app.route('/<filename:filename>')
def display_file(filename):
file_path = os.path.join('UPLOAD_PATH', filename)
with open(file_path) as file:
content = file.read()
return render_template('display_file.html', content=content)
I want to make a file uploader using Python, Flask, and HTML. If I upload a file I get:
Not Found
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
import os
from flask import Flask, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = './user/Tom/Files/'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', '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():
if request.method == ['POST']:
if 'file' not in request.files:
flash('Geen Bestand')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('Geen Bestand')
return redirect(request.url)
if not os.path.exists("user/Tom/Files/"):
os.makedirs("user/Tom/Files/")
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('uploaded_file',
filename=filename))
return render_template("index.html")
if __name__ == ('__main__'):
app.run(debug=True, port=8000)
<!DOCTYPE html>
<html>
<head>
<title>Upload a File!</title>
</head>
<body>
<form method="post" action="user/Tom/Files/" enctype="multipart/form-data">
<input type="file" id="customFile" name="file">
<input type="submit" name="Upload" value="Upload">
</form>
</form>
</body>
</html>
I deleted the action and the value
Now i have this:
<form method="post" enctype="multipart/form-data">
<input type="file" id="customFile" name="file">
<input type="submit" name="Upload">
</form>
But now it stay on de index.html but doesnt upload it to /user/Tom/Files/ ?