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
Related
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">
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.
The problem is i am able to upload file which are in the same directory as main.py but I am unable to upload other files which are not in the same folder of main.py, suppose - main.py is in c:\users\prabhat\upload\ and the file i am uploading the file is also in c:\users\prabhat\upload\ directory, but if there is file in c:\desktop\B.xlsx then if i upload, then it shows Error, file not found.
how an i resolve this??
index.html code
<form class="" action="data" method="post">
<input type="file" name="upload-file" value="">
<input type="submit" name="" value="Submit">
</form>
main.py
from flask import Flask, render_template, request
import pandas as pd
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
return render_template('index.html')
#app.route('/data', methods=['GET', 'POST'])
def data():
if request.method == 'POST':
file = request.form['upload-file']
return '''
successfully Done!
'''
if __name__ == '__main__':
app.run(debug=True)
You don't access files uploaded through flask via request.form but rather through request.files. This should get you a valid file handle:
if request.method == 'POST':
file = request.files['upload-file']
See https://flask.palletsprojects.com/en/2.2.x/patterns/fileuploads/ for more info.
Try file = request.files['upload-file'] instead of request.form, and I guess you want to save it to the server, do it with file.save("path/to/your/folder/filename.extension")
I am trying to put together a flask api endpoint that can take an image, drop it in a an 'uploads' folder and then perform an operation on it. The image will be sent from a reactjs front end. I have the beginnings of a python script that I know allows me to upload a photo via flask. But I want to alter it to:
lose the front end upload option instead giving me just the endpoint to upload the image
set it up to run a python script on that image once it lands in the uploads folder that extracts text
I've put below some of the pieces I have so far:
reactjs
#just the piece where i am sending an image to flask
fileUploadHandler =() => {
const fd = new FormData();
fd.append('image', this.state.selectedFile, this.state.selectedFile.name)
console.log('file is uploaded')
//axios.post('my_endpoint');
}
app.py
#from https://stackoverflow.com/questions/52152464/convert-normal-python-script-to-reset-api
import sumTwoNumbers
from flask import Flask, request
from flask_restful import Resource, Api
import os
from werkzeug.utils import secure_filename
import cv2
PROJECT_HOME = os.path.dirname(os.path.realpath(__file__))
UPLOAD_FOLDER = '{}/uploads/'.format(PROJECT_HOME)
app = Flask(__name__)
api = Api(app)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
ALLOWED_EXTENSIONS = set(['jpg','png'])
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))
_path = os.path.abspath("<FILE PATH>")
#uf = str(uuid.uuid4())
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=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=5000, debug=True)
imageToText.py
#script to run on the image that pulls text
import cv2
import pytesseract
import imutils
img = cv2.imread('note.PNG')
#use tesseract to convert image into strinf
text = pytesseract.image_to_string(img, lang='eng')
print(text)
I'm following the Flask tutorial for image uploading. I also decided to tinker with it a bit so that I can add other features. The website loads locally, but when I actually click on the upload button (after selecting a .png image), I get the following error:
Bad Request. The browser (or proxy) sent a request that this server could not understand.
I've read something about adding an else statement here:
Form sending error, Flask
But I'm not sure how to accommodate it for my needs.
Here is my code:
from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash
from werkzeug import secure_filename
import os
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'
#Add parameters for image uploads:
UPLOAD_FOLDER = '/upload_folder/'
ALLOWED_EXTENSIONS = set(['png','jpg','jpeg'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
##app.route('/')
##app.route('/<name>')
#Image uploads:
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.',1)[1] in ALLOWED_EXTENSIONS
#app.route('/',methods=['GET','POST'])
def upload_file():
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 '''
<!doctype html>
<title>Upload new File</title>
<h1>UPload new File</h1>
<form action="" method=post enctype=multpart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#Handle errors:
#app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'),404
#render template:
def flaskr(name=None):
return render_template('hello.html',name=name)
#Handle errors:
#app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'),404
if __name__ == '__main__':
app.run()
There is a typo in your html code:
<form action="" method=post enctype=multpart/form-data>
should be multipart and not multpart.