calling local python file in flask service - python

I have two python code, the first one is a flask python code(main.py) which collects image from the user and stored it in my local directory, and the second one is tesseract-ocr(ocrDetection.py) python code where the image are getting started to detect text in it.
Now I desired to integrate these two codes, by importing ocr code in flask [ import ocrDetection in main.py]
import os
#import magic
import urllib.request
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = set(['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('upload.html')
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
#app.route('/')
def usemain():
if request.method == 'POST':
import ocrDetection
ocrDetection.mask()
if __name__ == "__main__":
app.run(host='192.168.106.51')
this is not working properly if I give my OCR program after __name__=="__main__" like this
if __name__ == "__main__":
app.run(host='192.168.106.51')
import ocrDetection
it works only when I quit the server (ctrl+c), but I want to start my OCR program simultaniously after giving submit button

This will not work because you have two same routes ('/') which create conflict. I suggest that you create a new route for OCR e.g. '/ocr_detection' or create ocr_detection() as a module in a separate file.
To call OCR module, you can perhaps use it as API endpoint if you want to call from client like browser or as a module to simply call it from your backend (from within the views).
If you call it from within upload_file() module then it will be a sequential call and your browser has to wait until OCR is finished. But to avoid this, you can run periodic script which monitors the UPLOAD_DIR for new files and OCR them. This way your user browsing experience will also be much better.
....
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
ocr_detection(filename)
flash('File(s) successfully uploaded')
return redirect('/')
def ocr_detection(file):
import ocrDetection
ocrDetection.mask()
if __name__ == "__main__":
app.run(host='192.168.106.51')

Related

Flask website how to add uploaded file directly to firebase? [duplicate]

This question already has an answer here:
Upload image received via Flask to Firebase Storage
(1 answer)
Closed 7 months ago.
I have a flask web page where the user can upload files and on clicking the submit button, they get saved in a folder on my system(called UPLOAD_FOLDER in code).
My goal is to make it happen such that, on clicking the submit button, the chosen files get uploaded to my firebase inside a folder called pos instead of a local folder on my system.
Here's what my app.py currently looks like:
from flask import Flask, render_template, flash, request, redirect
from werkzeug.utils import secure_filename
import os
import urllib.request
import pyrebase
config={
#config stuff
}
app = Flask(__name__)
UPLOAD_FOLDER = r"C:\Users\mihir\settls\PO\POs\fbpdfs"
firebase=pyrebase.initialize_app(config)
storage=firebase.storage()
app.secret_key = "Cairocoders-Ednalan"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['pdf'])
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_file():
if request.method == 'POST':
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
if __name__ == '__main__':
app.run(debug=True)
Here's what I tried to change in the upload_file() function:
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
path_on_cloud="pos/"+filename
path_local=filename
storage.child(path_on_cloud).put(path_local)
flash('File(s) successfully uploaded')
return redirect('/')
But it doesn't work and is giving me a "No such file or directory error"
Firebase hosting does not have persistent storage by itself. It is common practice to store the file in Cloud Storage. An example can be found here, which saves the file as a temporary file before it is uploaded to Cloud Storage:
import os
import tempfile
import firebase
...
file = request.files['file']
temp = tempfile.NamedTemporaryFile(delete=False)
file.save(temp.name)
firebase.storage().put(temp.name)
# Remove temp file
os.remove(temp.name)

How to make a Frozen-Flask url generator for an uploaded file

I am trying to use frozen flask, and am running into problems with the URL generator. My app takes a csv file that the user uploads, and will download a modified version to the user's computer.
My question is this: how can I yield a url when the url depends on an uploaded file? I checked the documentation and there is nothing about this. How can I get the filename in my url generator?
Here is the relevant code from my app:
def download_file(name):
cleaning_script.clean(name)
return send_from_directory(app.config["UPLOAD_FOLDER"], 'output.csv')
And here is the url generator
#freezer.register_generator
def download_file():
yield {'name':<What do I put here?>}
if __name__ == '__main__':
freezer.freeze()
Here is a sample of what my webapp looks like.
It's nothing more than a simple upload form, which is handled by this code
#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 render_template('index.html')

Flask - Why doesn't this let me import image files?

I am trying to make an application that allows users to upload images from their computer. This is as part of my CS50x final project, so I'm working in the CS50 IDE. Here is the code for my application:
application.py
import os
from flask import *
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route('/')
def myindex():
return render_template("file_upload_form.html")
#app.route('/upload', methods = ['POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
file.save(os.path.join(app.config['UPLOAD_FOLDER'], "test.jpg"))
return redirect("/")
if __name__ == "__main__":
app.run(debug=True)
file_upload_form.html
<html>
<head>
<title>upload</title>
</head>
<body>
<form action = "/upload" method = "post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type = "submit" value="Upload">
</form>
</body>
</html>
For the vast majority of files, when I submit the form, I get a 500 Internal Server Error with no traceback or explanation. Curiously though, some files it seems to work with. I have found two images that work: both JPEGs and both relatively small. All other images I have tried have caused the error.
I cannot work out what is causing the Server Error, or why some images work and others don't. Can anyone see any reason why it wouldn't work for other images?
Thanks
I tested out your code and it worked fine on my side, but there is a couple of additions i would make, just to make it more robust.
You are calling all your uploads test.jpg and there is no mechanism in place to ensure that the file that gets uploaded is a jpg file. So technically, i could upload a pdf and it would be renamed in to a test.jpg.
A better method is to just give the file - the same name it had, including the extension. If you want to re-name the file, rather strip the extension first and add it to the new filename like so:
ext = file.filename.rsplit('.', 1)[1].lower()
newFilename = 'newname.{}'.format(ext)
Also there is no MAX_CONTENT_LENGTH - I would add that as well.
So i re-wrote your python code to look like this:
import os
from flask import *
from werkzeug.utils import secure_filename
app = Flask(__name__)
UPLOAD_FOLDER = './uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['ALLOWED_IMAGES'] = set(['png', 'jpg', 'jpeg'])
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
def allowed_image(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_IMAGES']
#app.route('/')
def myindex():
return render_template("index.html")
#app.route('/upload', methods = ['POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
if file and allowed_image(file.filename):
file.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file.filename)))
return redirect(request.url)
if __name__ == "__main__":
app.run(debug=True)
You are sending the post to: <form action = "/success"...>
Where is your /success handler?
UPDATE:
Try:
if request.method == 'POST':
print(request.files)
print(request.form)
print(request.POST)
You need to check the logs to see what there error is.

Uploading images to a Flask server using FilePond (React component)

I have a locally hosted Flask server and a small React application. I'm trying to use FilePond as an easy solution for image uploading. FilePond takes care of sending each image to the server.
So the problem I'm obviously having is with the backend code. I've set up my server like this, per Flask's docs
UPLOAD_FOLDER='/images'
ALLOWED_EXTENSIONS = set(['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():
print(request.files)
if request.method == "POST":
# check if the post request has the file part
if 'file' not in request.files:
print('No file part')
return make_response("No File Part", 400)
file = request.files["file"]
# if user does not select file, browser also submit an empty part
# without filename
if file.filename == '':
print('No selected file')
return make_response("No Selected File", 400)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename) # filenames can be dangerous!
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return make_response("Success", 201)
However, when put a
print(request.files)
statement at the beginning of the upload_file() function, it seems that this is the request the server is receiving:
ImmutableMultiDict([('images', <FileStorage: 'imageName.jpg' ('image/jpeg')>)])
and I have no idea how to deal with that. I don't know if 'images' is where 'file' is supposed to be. I'm just not really sure where to go from here or what to do with the data being received. I don't know what is, I've never seen that <> syntax being used.
Can anyone help?
Here's a pastebin for the whole server-side code
Thank you!
Here's a proof of concept app that lets you upload multiple images using a form:
Note the enctype="multipart/form-data" attribute of the form, without this you cannot upload files.
Also note the multiple attribute of the file input. This allows client to select multiple files. You need to use request.files.getlist() to obtain the list of all uploaded files.
Once you generate the path to save the file, saving a werkzeug.FileStorage object is is just calling its .save(path_to_save) method.
from flask import Flask, request, render_template_string, redirect, abort
from werkzeug import secure_filename
from pathlib import Path
UPLOAD_DIR: Path = Path(__file__).parent / 'uploads'
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
app = Flask(__name__)
def is_valid_upload(upload) -> bool:
# some validation logic
return Path(upload.filename).suffix.lower() in ['.jpg', '.jpeg']
#app.route('/', methods=['GET', 'POST'])
def upload():
html = '''
<form action='/' method='POST' enctype="multipart/form-data">
<input type="file" name='images' multiple>
<button>Upload</button>
</form>
'''
if request.method == 'GET':
return html
uploaded_files = request.files.getlist('images')
if not uploaded_files or not uploaded_files[0].filename:
return redirect('/')
valid_uploads = list(filter(is_valid_upload, uploaded_files))
if not valid_uploads:
return 'invalid image(s)', 400
for upload in valid_uploads:
filename = secure_filename(upload.filename)
save_path = str(UPLOAD_DIR / filename)
upload.save(save_path)
return 'uploaded'
if __name__ == "__main__":
app.run()

Getting a requested URL not found error when running flask code

Created a web app and have managed to build a function to clean up csv files from Google my Business exports. However when I run the function with the code I have written I get the following error message:
Not Found
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
Not sure where I am going wrong
mport os
import pandas as pd
from flask import Flask, request, redirect, url_for
from flask import Flask, make_response
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
def transform(text_file_contents):
disc = open('clean.csv')
disc2 = open('clean_two.csv','w')
#cleaning up csv
for row in disc:
row = row.strip()
row = row[1:-1]
row = row.replace('""','"')
disc2.write(row+'\n')
disc2.close()
disc.close()
discovery = pd.read_csv('clean_two.csv')
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
#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 action="\transform" method="post" enctype="multipart/form-data">
<p><input type="file" name="file">
<input type="submit" value=Upload>
</form>
'''
#app.route('/transform',methods=["POST"])
def transform_view():
request_file=request.files['file']
request_file.save('clean.csv')
if not request_file:
return "No file"
result = transform()
print(result)
response = make_response(result)
response.headers["Content-Disposition"] ="attachment; filename=result.csv"
return response
if __name__=='__main__':
app.run()
Note: I get this error message after running the script and uploading a csv. The desired outcome is uploading a csv, and showing it on my screen as a cleaned up data table
There are multiple problems here. First, Wondercricket is correct about the form action. It needs to be changed to "/transform".
Once that's done, you're still getting an Internal Server Error. In this case, your transform function is defined as taking a single parameter, but it's not being called with one. Simply change
def transform(text_file_contents):
to
def transform():
That should allow the upload to happen, and the transform will now run. However, there's still one last problem. transform returns a pandas DataFrame, which Flask can't use as a response. Change
response = make_response(result)
to
response = make_response(result.to_csv())
and you should be good to go.

Categories