Flask HTTP Server won't allow upload of multiple files at once - python

import os
from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename
UPLOAD_FOLDER = '/home/ubuntu/shared/'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
file = request.files['file']
if file:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('index'))
return """
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method="post" enctype="multipart/form-data">
<p><input type="file" multiple="" name="file">
<input type="submit" value="Upload">
</form>
<p>%s</p>
""" % "<br>".join(os.listdir(app.config['UPLOAD_FOLDER'],))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, debug=False)
If I launch the server and select 2 files through the form, it only uploads one of them. I tried for serveral hours and read about 15 topics on it, including the documentation.
Nada :c
Edit:
I also tried changing:
file = request.files['file']
into:
file = request.files.getlist('file')
would not work either. The type of quotes have no effect either. Wasn't that a python3 thing?

import os, ssl
from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename
UPLOAD_FOLDER = '/home/ubuntu/shared/'
certfile = "/home/ubuntu/keys/fullchain.pem"
keyfile = "/home/ubuntu/keys/privkey.pem"
ecdh_curve = "secp384r1"
cipherlist = "ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305"
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
sslcontext.options |= ssl.OP_NO_TLSv1
sslcontext.options |= ssl.OP_NO_TLSv1_1
sslcontext.protocol = ssl.PROTOCOL_TLSv1_2
sslcontext.set_ciphers(cipherlist)
sslcontext.set_ecdh_curve(ecdh_curve)
sslcontext.load_cert_chain(certfile, keyfile)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
my_data = request.files.getlist('file')
my_pass = request.form['password']
if my_data and my_pass == 'yakumo':
for file in my_data:
my_handler(file)
return redirect(url_for('index'))
return """
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file multiple name=file>
<input type="password" name="password" value="">
<input type=submit value=Upload>
</form>
<p>%s</p>
""" % "<br>".join(os.listdir(app.config['UPLOAD_FOLDER'],))
def my_handler(f):
filename = secure_filename(f.filename)
f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, ssl_context=sslcontext, threaded=True, debug=False)
I made a very rookie mistake and didn't for-loop over the multiple files being uploaded. The code here was tested without issues with 4 simultaneous file uploads. I hope it will be useful to someone.
Edit: Code updated with some sweet TLS_1.2 and a password field. Enjoy a reasonably secure upload server. Password is transferred over HTTPS.

Related

How to read single file in my data using Flask

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)

Render image from gridfs on html page using flask

I want to render an image from gridfs on my html pyge using flask.
I store the image in my mongodb using gridfs with one button and also store the ObjectId of the image in a serverside session using Flask-Session.
When I click on another button, I get the correct ObjectId of the image stored before via my session and then want to render this image from gridfs in my html page, but I don't know how to do it.
My app.py file:
from flask import Flask, render_template, request, redirect, session
from werkzeug.utils import secure_filename
from pymongo import MongoClient
from gridfs import GridFS
from flask_session import Session
DB = 'test-grid'
COLLECT = 'test-session'
client = MongoClient('mongodb://127.0.0.1:27017')
db = client[DB]
fs = GridFS(db)
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16*1024*1024
app.config['SESSION_TYPE'] = 'mongodb'
app.config['SESSION_MONGODB'] = client
app.config['SESSION_MONGODB_DB'] = DB
app.config['SESSION_MONGODB_COLLECT'] = COLLECT
Session(app)
#app.route("/")
def home():
return render_template("index.html")
#app.route('/upload', methods=['POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
filename = secure_filename(f.filename)
f_id = fs.put(f, filename=filename)
session['f_id'] = f_id
session['filename'] = filename
return redirect('/')
#app.route('/display', methods=['GET'])
def display_file():
if request.method == 'GET':
f = fs.get(session['f_id'])
image = f.read()
return render_template("index.html", user_image=image)
if __name__ == "__main__":
app.run(debug=True)
My index.html file:
<html lang='en'>
<head>
<meta charset='UTF-8'/>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" onchange="this.form.submit()" name="file" autocomplete="off" required>
</form>
<form method="get" action="/display">
<input type="submit" value="Display">
</form>
<img src="{{ user_image }}" alt="Show image here"/>
</body>
</html>
My requirements.txt file:
Flask
Flask-Session
pymongo
But this doesn't work and I get the following output:
Output
Can someone please help me fix this? Maybe with examples I can look up.

Insert or write data to .txt file with flask

I have tried the existing code, but it still fails. My problem is how to insert data into the .txt file using the Flask form.
The following is my app.py code:
from flask import Flask, request, render_template
from os import listdir
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['GET', 'POST'])
def my_form_post():
input_nopol = request.form.get['nopol']
if request.method == 'POST' and input_nopol:
print(listdir)
with open('/home/pi/web-server/nopol.txt', 'w') as f:
f.write(str(input_nopol))
return render_template('index.html', nopol=input_nopol)
if __name__ == "__main__":
app.run(host='192.168.1.2', port=8080, debug=True)
The following is a simple code for the form at index.html in template folder:
<!DOCTYPE html>
<head>
<title>Hello</title>
</head>
<body>
<form method="POST">
<input name="text">
<input type="submit">
</form>
</body>
</html>
I am very grateful for the help and solution from all of you.
Update your code as below
index.html
<!DOCTYPE html>
<head>
<title>Hello</title>
</head>
<body>
<form action="" method="POST">
<input name="text_box">
<input type="submit">
</form>
</body>
</html>
app.py
from flask import Flask, request, render_template
from os import listdir
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['POST'])
def my_form_post():
input_nopol = request.form['text_box']
if request.method == 'POST':
with open('nopol.txt', 'w') as f:
f.write(str(input_nopol))
return render_template('index.html', nopol=input_nopol)
if __name__ == '__main__':
app.debug = True
app.run()
<!DOCTYPE html>
<head>
<title>Hello</title>
</head>
<body>
<form action="" method="POST">
<input name="text_box">
<input type="submit">
</form>
from flask import Flask, request, render_template
from os import listdir
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['POST'])
def my_form_post():
input_nopol = request.form['text_box']
if request.method == 'POST':
with open('nopol.txt', 'w') as f:
f.write(str(input_nopol))
return render_template('index.html', nopol=input_nopol)
if __name__ == '__main__':
app.debug = True
app.run()

Flask Upload File Not Found

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/ ?

Upload two different file in two different fields

I'm using flask to develop webapp and I have two different files to upload to two different locations and as far as I search through the internet I only find explanation to upload one or multiple together in one file field and it works fine.
here is the code i used to upload one file:
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 > 0:
filename = secure_filename(file.filename)
file.save(os.path.join(UPLOAD_FOLDER , filename))
return redirect(url_for('index'))
can someone help me with that
The name of the input will be the key which you retrieve the file from request.files
html:
<input type="file" name="first_file" />
<input type="file" name="second_file" />
Flask:
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
first_file = request.files['first_file']
second_file = request.files['second_file']
... # do stuff with files
Documentation.
here is the whole code:
import os
from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename
import sys
sys.path.insert(0, '/home/muteb/Desktop/test')
UPLOAD_FOLDER = '/home/muteb/Desktop/test/'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
file1 = request.files['file1']
file2 = request.files['file2']
if file1 > 0:
filename1 = secure_filename(file1.filename)
file1.save(os.path.join(UPLOAD_FOLDER , filename1))
if file2 > 0:
filename2 = secure_filename(file2.filename)
file2.save(os.path.join(UPLOAD_FOLDER , filename2))
return redirect(url_for('index'))
return """
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file1>
<input type=file name=file2>
<input type=submit value=Upload>
</form>
<p>%s</p>
""" % "<br>".join(os.listdir(app.config['UPLOAD_FOLDER'],))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5002, debug=True)

Categories