Convert normal Python script to REST API - python

Here I have an excel to pdf conversion script. How can I modify it to act as a REST API?
import os
import comtypes.client
SOURCE_DIR = 'D:/projects/python'
TARGET_DIR = 'D:/projects/python'
app = comtypes.client.CreateObject('Excel.Application')
app.Visible = False
infile = os.path.join(os.path.abspath(SOURCE_DIR), 'ratesheet.xlsx')
outfile = os.path.join(os.path.abspath(TARGET_DIR), 'ratesheet.pdf')
doc = app.Workbooks.Open(infile)
doc.ExportAsFixedFormat(0, outfile, 1, 0)
doc.Close()
app.Quit()

You can use Python's Flask lightweight Rest Framework to make your program accessible for REST Calls. Check this tutorial: http://flask.pocoo.org/docs/1.0/tutorial/
There you can simply get the file input in POST format and once the file is converted send a downloadable link to the end user. You have to tweak this code I wrote with a friend for similar purposes:
import os
from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename
PROJECT_HOME = os.path.dirname(os.path.realpath(__file__))
UPLOAD_FOLDER = '{}/uploads/'.format(PROJECT_HOME)
ALLOWED_EXTENSIONS = set(['txt','pdf', 'vcf'])
app = Flask(__name__)
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))
_path = os.path.abspath("<FILE PATH>")
uf = str(uuid.uuid4())
# DO YOUR AMAZING STUFF HERE
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=5001, debug=True)

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">

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

How do I send an image taken in react to a flask api and run python script?

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)

No columns to parse from file after trying to process csv on flask

I am trying to process a csv file on flask with the intention of cleaning it up. I know the actual clean up script works the way it should. However, I am new to flask and for some reason when I run my code I receive the error message:
pandas.errors.EmptyDataError pandas.errors.EmptyDataError: No columns
to parse from file
Here is the code I am using for this
import os
import pandas as pd
from flask import Flask, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = './Downloads/gmbreports'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
ALLOWED_EXTENSIONS = 'csv'
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('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('You need to upload a csv 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>Google My Business Discovery Report Builder</title>
<h1>Upload GMB Discovery csv</h1>
<form method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
from flask import send_from_directory
#once you upload the file you get cleaned up visu
#app.route('/uploads/<filename>')
def uploaded_file(filename):
path = UPLOAD_FOLDER + "/" + filename
file_one = open(path)
file_two = open(path,'w')
for row in file_one:
row = row.strip()
row = row[1:-1]
row = row.replace('""','"')
file_two.write(row+'\n')
file_two.close()
file_one.close()
discovery=pd.read_csv(path)
return discovery
discovery_clean=discovery.iloc[1:]
cols=list(discovery_clean.columns[4:])
discovery_clean[cols]=discovery_clean[cols].apply(pd.to_numeric,errors='coerce')
return discovery_clean
if __name__=='__main__':
app.run(debug=True)
I have also attached a sample of the dataframe i am trying to clean
Sample File

upload image flask error

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.

Categories

Resources