Flask image variable is "sticking" - python

I have a Flask app that works the first time, after that the html always show the first predicted image even though the new predicted image is written to the folder
I have tried deleting the image from the upload folder, but the original prediction is staying.
Below is my flask app
UPLOAD_FOLDER = ''
ALLOWED_EXTENSIONS = set(['jpg', 'png'])
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)
#filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image = open_image(filename)
image_url = url_for('uploaded_file', filename=filename)
think = learn.predict(image)
think_np = np.array(think[1])
think_np.shape = (256,256)
think_np = think_np.astype(int)
think_np[think_np > 0] = 255
think_im = Image.fromarray((think_np).astype('uint8'), mode='L')
think_im.save(os.path.join(app.config['UPLOAD_FOLDER'], 'think2_im.png'))
think_im_url = url_for('uploaded_file', filename='think2_im.png')
print(think_im_url)
#image.show(y=learn.predict(image)[0])
return '''<h1>The cell image is:</h1>
<img src= "{}" height = "85" width="200"/>
<h1>The cell segmentation is:</h1>
<img src= "{}" height = "85" width="200"/>'''.format(image_url, think_im_url)
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload an image of Cells</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)
The first time I run this everything works great. But, if I run again, the think_im_url always shows the first predicted image. Even if I restart the kernel. Even if I go into the upload folder and delete the image. Also, though, the predicted image written to the upload folder is the correct (new) predicted image. Just what is showing in the HTML always stays the same.
If I go into the code and change the name, i.e. change "think2_img.png" to "think3_img.png", then the process starts again. The first time works great, but even though new predictions overwrite the "think" prediction in the upload folder, the HTML only shows the original prediction.
The image_URL changes each time like it is supposed to.

Related

how to use Flask to save both uploaded file and user text input in json

in html, I have
<form method="POST" enctype="multipart/form-data" action="/">
<input type="number" name="speed " id="speed">
<input type="file" id="stl_file">
<input type="submit" value="submit">
</form>
I would like to save the value for speed in json file and save the uploaded stl file as well.
What I did in my app.py is
from flask import Flask, render_template, request,flash, redirect, url_for
from werkzeug.utils import secure_filename
import os
import json
app = Flask(__name__)
ALLOWED_EXTENSIONS = {'stl','STL'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route("/")
def index():
return render_template('main.html')
#app.route('/' , methods=['POST'])
def get_data():
if request.method == 'POST':
results =request.form
file = request.files['stl_file']
with open('file.json','w') as f:
json.dump(results, f)
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
# 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(filename)
return redirect(url_for('index'))
return render_template('main.html')
if __name__ == '__main__':
app.run()
I can run it and I see my main page. However, when I input a number into speed, upload a file, and click submit, I get
Bad Request
The browser (or proxy) sent a request that this server could not understand.
Any suggestion on that? Thanks in advance.
You haven't defined the name attribute of file.
<input type="file" name="stl_file" id="stl_file">

In Flask, how do I store a user submitted file temporarily to manipulate it and return it back?

So I've been working on a Flask application where the user submits a file to a form, the server takes it and manipulates it, then returns the edited file back to the user. I am new to Flask and web dev in general, so bear with me. I have already set up the website with the form and a filefield, but Im not exactly sure how I can get the data from the file. Do i have to store it on the server? If I do, do I have to delete after im done?
Here is what I've got so far in my routes
#app.route('/mysite', methods=['post', 'get'])
def mysite():
form = mysiteform()
if request.method == 'POST' and form.validate():
file = form.file.data.read()
filename = secure_filename(file.filename)
return render_template('mysite.html', title = 'hello world!', form=form)
In Flask official documentation site, there is a file uploader example as below:
#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 '''
<!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>
'''
Here is how you can get the file content: file = request.files['file'] and of course you can do further manipulation on the file.
Here is how you can save the file file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)). It's really up to you if you want to save the file and return the file later or just modify it in memory and return it immediately.

How can I add image file in SQLite database using Flask, Python

I'm writing a small web-shop using Python and web-framework Flask.
I'm trying to add image file in SQLite database using this
#app.route('/new_product_reg', methods=['POST', 'GET'])
def new_product_reg():
if request.method == 'POST':
img_name = request.form['product_img']
product_img = readImage(img_name)
product_img_binary = lite.Binary(product_img)
product_data = NewProduct(product_img=product_img_binary)
try:
db.session.add(product_data)
db.session.commit()
return redirect('/new_product_reg')
except:
return "ERROR!"
Where readImage is
def readImage(img_name):
try:
fin = open(img_name, 'rb')
img = fin.read()
return img
except:
print("ERROR!!")
Form where I taked the image:
<form enctype="multipart/form-data" method="post">
<input type="file" name=product_img id="product_img"><br>
<input type="submit" value="Submit">
</from>
And the class of database where I want to add image looks like that:
class NewProduct(db.Model):
product_img = db.Column(db.BLOB())
def __repr__(self):
return '<NewProduct %r>' % self.id
So, the problem is, when I added image by pressing "Add Image" button in form and pressed "Submit" button I get the BadRequestKeyError 400. The debugger said that the problem is in img_name = request.form['product_img']. So how can I fix that and what I'm doing wrong?
At first I want to say that storing large and medium pictures directly in SQLite is not a very good solution. Learn more here: https://www.sqlite.org/intern-v-extern-blob.html
For your problem, try to do as in the documentation:
https://flask.palletsprojects.com/en/1.1.x/patterns/fileuploads/
Note there is used:
# 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)
And perhaps this article will also help you:
Python SQLite BLOB to Insert and Retrieve file and images

Uploading and Processing files with Flask Rest API

I want to create a REST API using Flask. I have two files at any given time, I will call my API and send these two files, a python script will run on the API side and send me back a JSON Response. Now this is the overall idea of my application , but I don't know how to do all this. As I do not want to save those two files, just take them as an Input and send the result back, I don't think i will need to save the files. But I do not know how to send files to the API, logic part is ready, I just need to know how to send two files, process them and send back the response in just one API call. Thanks in advance
I have just setup the basic API till now.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'Server works'
if __name__== '__main__':
app.run(debug=True)
Found this on the Flask documentation:
import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'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':
# 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>
'''
In your API backend, you will receive the file by using file = request.files['file']. The name "file" comes from the name of the input tag in the HTML Form you are using to send the file to your backend.
'''
<!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>
'''
In this example, the backend is saving the uploaded files to UPLOAD_FOLDER. This example is also using some exception handling to make sure that the user is uploading the correct type of file types.
[EDIT] I misread your question. If you just want to send back a JSON response instead of JSON containing the files content you would do this:
return jsonify({"response": "success"})
Finally, here's a link to the full Flask documentation

Uploading multiple files with Flask

Is there a way to receive multiple uploaded files with Flask? I've tried the following:
<form method="POST" enctype="multipart/form-data" action="/upload">
<input type="file" name="file[]" multiple="">
<input type="submit" value="add">
</form>
And then printed the contents of request.files['file']:
#app.route('/upload', methods=['POST'])
def upload():
if not _upload_dir:
raise ValueError('Uploads are disabled.')
uploaded_file = flask.request.files['file']
print uploaded_file
media.add_for_upload(uploaded_file, _upload_dir)
return flask.redirect(flask.url_for('_main'))
If I upload multiple files, it only prints the first file in the set:
<FileStorage: u'test_file.mp3' ('audio/mp3')>
Is there a way to receive multiple files using Flask's built-in upload handling? Thanks for any help!
You can use method getlist of flask.request.files, for example:
#app.route("/upload", methods=["POST"])
def upload():
uploaded_files = flask.request.files.getlist("file[]")
print uploaded_files
return ""
#app.route('/upload', methods=['GET','POST'])
def upload():
if flask.request.method == "POST":
files = flask.request.files.getlist("file")
for file in files:
file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
It works for me.
for UPLOAD_FOLDER if you need add this just after app = flask.Flask(name)
UPLOAD_FOLDER = 'static/upload'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Using Flask 1.0.2+:
files = request.files.getlist("images")
Where images is the key of the key/value pair. With the Value being the multiple images.
this is a working solution for flask version '1.0.2':
images = request.files.to_dict() #convert multidict to dict
for image in images: #image will be the key
print(images[image]) #this line will print value for the image key
file_name = images[image].filename
images[image].save(some_destination)
basically, images[image] has an image file with save function added to it
Now do whatever you like to do with the data.

Categories

Resources