While following the Flask documentation / tutorials on how to upload a file I used this code:
main.py:
from flask import render_template, jsonify, Flask, redirect, url_for, request
from app import app
import random
import os
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np
#app.route('/')
#app.route('/upload')
def upload_file2():
return render_template('index.html')
#app.route('/uploaded', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
path = os.path.join(app.config['UPLOAD_FOLDER'], f.filename)
model= ResNet50(weights='imagenet')
img = image.load_img(path, target_size=(224,224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
preds_decoded = decode_predictions(preds, top=3)[0]
print(decode_predictions(preds, top=3)[0])
f.save(path)
return render_template('uploaded.html', title='Success', predictions=preds_decoded, user_image=f.filename)
#app.route('/index')
def index():
return render_template('index.html', title='Home')
#app.route('/map')
def map():
return render_template('map.html', title='Map')
#app.route('/map/refresh', methods=['POST'])
def map_refresh():
points = [(random.uniform(48.8434100, 48.8634100),
random.uniform(2.3388000, 2.3588000))
for _ in range(random.randint(2, 9))]
return jsonify({'points': points})
#app.route('/contact')
def contact():
return render_template('contact.html', title='Contact')
Everything seems to be fine in the code. I have checked several times.
Well when running it on localhost on my Windows machine.
I get an 404 http-status-code (page not found).
I tried: on http://localhost:5000/ and http://localhost:5500/
Also I cleaned my browser...
Change
#app.route('/uploaded', methods = ['GET', 'POST'])
To
#app.route('/upload.php', methods = ['GET', 'POST'])
Or, change your front end form to post to uploaded.
Related
I did create a machine learning model using Pytorch which i want to use as a webservice using Flask. The problem is that i don't understand how i can pass a json-String to the url. Below is my code that I wrote to do some tryouts with my model and Flask:
from modelLoader import Model
from imageLoader import Img
import os
from flask import Flask, jsonify, request
app = Flask(__name__)
classes = ["dummy-image", "product-image"]
model_path = os.path.join("data", "models", "model1709", "model1709")
image_path = os.path.join("data", "images", "dummy_images")
m1 = Model(model_path, classes, "cpu")
#app.route('/predict', methods=['POST', 'GET'])
def predict():
# case for handle json
input_data = request.get_json()['url']
if isinstance(input_data, list):
for elem in input_data:
img_elem = Img(url=elem)
res = img_elem.get_prediction(m1)
return jsonify({"type": "bulk_upload"})
img_inpdata = Img(url=input_data)
res, info = img_inpdata.get_prediction(m1)
return jsonify({input_data: res, "info": str(info)})
if __name__ == '__main__':
app.run(debug=True)
This would be a request that I want to make using this code:
POST http://192.168.178.13:5000/predict HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"url" : "https://socialistmodernism.com/wp-content/uploads/2017/07/placeholder-image.png"
}
How exactly can I get the prediction for the image inside the json-string, by passing this json-string to the application?
Here the two classes model and imageLoader for completeness:
from torch import argmax, device, load, nn
class Model:
def __init__(self, path, class_list=None, dvc=None):
if class_list is None:
class_list = [0, 1]
if dvc is None:
dvc = 'cpu'
self.class_list = class_list
self.model = load(path, map_location=device(dvc))
num_ftrs = self.model.fc.in_features
self.model.fc = nn.Linear(num_ftrs, len(class_list))
self.model.eval()
import torchvision.transforms as transforms
import io
from PIL import Image
from torch import argmax, device, load, nn
import requests
class Img:
def __init__(self, url=None, image=None, image_bytes=None):
if url:
img = Image.open(requests.get(url, stream=True).raw)
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format=img.format)
self.image_bytes = img_byte_arr.getvalue()
elif image:
f = image.read()
self.image_bytes = bytearray(f)
elif image_bytes:
self.image_bytes = image_bytes
def transform_image(self):
data_transforms = transforms.Compose([transforms.Resize((224, 224)),
transforms.CenterCrop(
224), transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224,
0.225])])
image = Image.open(io.BytesIO(self.image_bytes)).convert('RGB')
return data_transforms(image).unsqueeze(0)
def get_prediction(self, model):
tensor = self.transform_image()
output = (model.model(tensor))
sm = nn.Softmax(output)
best = output.argmax().item()
return model.class_list[best], sm
You cannot do a POST request directly from the browser URL box. There are many applications to test your API and my favorite one is postman. You can also use the curl command tool.
If you want to use the browser URL box only, then consider using the GET request. The format of GET request is <URL>?parameter1=value1¶meter2=value2. You can access the value of the parameter in flask using the request module. For example, if your service is at http://192.168.178.13:5000/predict. You can send it as http://192.168.178.13:5000/predict?url=your-url. And you can fetch it in flask as
from flask import request
my_url = request.args.get("url")
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
#app.route('/predict', methods=['POST','GET'])
def predict():
model = joblib.load('rf_grid.pkl')
data = request.get_json()
prediction = model.predict([[np.array(data['Age'],data['SipSp'],data['Parch'],
data['Fare'],data['Sex_male'],
data['Cabin_Rare'],data['Embarked_S'])]])
output = prediction[0]
return jsonify(output)
if __name__ == '__main__':
app.run(debug=True)
This is a flask file that I'm running under app.py
import requests
import json
url ='http://127.0.0.1:5000/predict'
dictionary = {'Age':50, 'SipSp':1, 'Parch':1,'Fare':150,'Sex_male':1,'Cabin_Rare':0,'Embarked_S':1}
r = requests.post(url, json = dictionary)
print(r.json())
This is the file I'm running under requests.py. When I run this file I get the error:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
How do I get rid of this error and for my requests.py to run?
There is an error in your API logic. I have commented core logic portion and returned JSON response. And It it's not giving any error.
import numpy as np
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
#app.route('/predict', methods=['POST','GET'])
def predict():
# model = joblib.load('rf_grid.pkl')
# data = request.get_json()
# prediction = model.predict([[np.array(data['Age'],data['SipSp'],data['Parch'],
# data['Fare'],data['Sex_male'],
# data['Cabin_Rare'],data['Embarked_S'])]])
# output = prediction[0]
output = {"ok": True}
return jsonify(output)
if __name__ == '__main__':
app.run(debug=True)
If you can please share rf_grid.pkl file So, I can help with that.
I have a little flask application, it is mostly written with methods (just one class).
Can someone explain me - example would be great - why I am receiving 1 missing argument after adding self to method declaration?
Here is a code:
from __future__ import print_function
from flask import Flask, render_template, make_response
from flask import redirect, request, jsonify, url_for
from multiprocessing import Value
from flask_classful import FlaskView
#from settings import *
from utils.settings import *
import logging
import linecache
import os
import simplejson as json
import mysql.connector
counter = Value('i', 0)
app = Flask(__name__)
class FlaskCLS(FlaskView):
app.debug = False
app._static_folder = os.path.abspath("templates/static/")
#app.route('/v1/api/cords', methods=['GET', 'POST', 'OPTIONS'])
def snd_post():
res = make_response({'x': '55.333', 'y': '18.666'})
return res
#app.route('/', methods=['GET', 'POST', 'OPTIONS'])
def index():
result = []
data = request.data
with counter.get_lock():
counter.value += 1
out = counter.value
with open(str(out), 'a') as dumping:
json.dump(data, dumping)
# ----------------------parser-section------------
with open(str(out), 'r+') as file:
content = file.readlines()
for line in content:
result.append(line.replace('\\', "").replace('"', "").
replace('{', "").replace('}', '').
replace(']', '').replace(',','\n').
replace('[',''))
f = open(str(out), 'w')
f.write('')
f.close()
with open(str(out), 'a') as appending:
appending.write('')
for line in result:
appending.write(line)
# --------------------cords-grabbing-------------
x = linecache.getline(str(out), 1)
y = linecache.getline(str(out), 2)
fx = open('x', 'w')
fy = open('y', 'w')
fx.write(x)
fx.close()
fy.write(y)
fy.close()
mydb = mysql.connector.connect(
host=db_host,
user='root',
auth_plugin='mysql_native_password',
password=password,
buffered=buffered,
database=database)
mycursor = mydb.cursor()
mycursor.execute('select nazwa, x, y, SQRT(POW(69.1 * (x - 54.111), 2) + POW(69.1 *(18.222 - y)\
* COS(x / 57.3), 2)) as distance from wet_dane having distance <125 order by distance;')
mycursor.fetchall()
mydb.commit()
# ---------------------empty-files----------------
str_directory = '/var/www/html/'
list_files = [x for x in os.listdir(str_directory) if x[0] != '.']
for each_file in list_files:
file_path = '%s/%s' % (str_directory, each_file)
if os.path.getsize(file_path) == 0:
os.remove(file_path)
else:
pass
return render_template('layouts/index.html')
flask = FlaskCLS()
# ---------------------runner-section-------------
if __name__ == '__main__':
log = logging.getLogger('werkzeug')
log.disabled = True
app.run(host, port, debug, ssl_context=context)
My point is - how properly add self to index and snd_post methods?
I want to pass - for example - x variable from index to snd_post in the same class.
Without self flask doesn't allow me to do such an operation.
Thanks.
I don't have experience with Flask-Classful, but it looks that you are supposed to register the routes to the app this way:
class QuotesView(FlaskView):
def index(self):
return "Hello"
QuotesView.register(app)
Instead of the #app.route(...) decorator.
Ok, i've made a solution for this, now my main python file looks like this:
from __future__ import print_function
from flask import Flask, render_template, make_response
from multiprocessing import Value
from utils.settings import *
from py_methods.post import Post
from py_methods.db_connect import Db_conn
from py_methods.empty_files_del import DeleteEmpty
from py_methods.files_operations import Files
import logging
import os
app = Flask(__name__)
app.debug = False
app._static_folder = os.path.abspath("templates/static/")
#app.route('/v1/api/cords', methods=['GET', 'POST', 'OPTIONS'])
def snd_post():
return Post.snd_post()
class Main():
#app.route('/', methods=['GET', 'POST', 'OPTIONS'])
def index():
Files.parsing()
DeleteEmpty.del_empty()
Db_conn.wet_db()
return render_template('layouts/index.html')
# ---------------------runner-section-------------
if __name__ == '__main__':
log = logging.getLogger('werkzeug')
log.disabled = True
app.run(host, port, debug, ssl_context=context)
So it's just a runner - every method I wrote has own file and own class. This allow me to inheritance the variables. We can close this topic. Thansk for the answers.
Hello I am making an small page to show my results I am working in a project about sentiment analysis first I have the following labels:
senti=["furious","angry","angry0","Indiferent","happy","enthusiastic","Euphoric"]
I show this labels depending of the result of a predict function that I performed using keras, at this moment all is working well I wish to show an image depending of the label of above I tried creating an array with the path of the images as follows, I am not sure how to write the image function,
images=['home/image0.jpg','home/image1.jpg','home/image2.jpg','home/image3.jpg','home/image4.jpg','home/image5.jpg','home/image6.jpg']
def image():
This is the function that perform the predict, at this moment it is just showing a label of above, I would like to also display a distinct image, so I need to modify the following function:
def predict(text):
seqs = tok.texts_to_sequences([text])
print(text)
word_index = tok.word_index
print('Found %s unique tokens.' % len(word_index))
sequence_pred = sequence.pad_sequences(seqs, maxlen=MAX_SEQUENCE_LENGTH)
print(sequence_pred)
prediction = model.predict(sequence_pred)
print(prediction)
return senti[np.argmax(prediction[0])]
#app.route("/", methods=['GET', 'POST'])
def index():
print(request.method)
if request.method == 'POST':
q=request.form['querytext']
prediction=predict(q)
return render_template("result.html",prediction=prediction,text=q)
return render_template("main.html")
Since I am a beginner at flask I would like to appreciate support or suggestions to overcome this situation thanks for the help,
After a very useful feedback I tried:
senti=["furious","angry","angry0","Indiferent","happy","enthusiastic","Euphoric"]
def predict(text):
seqs = tok.texts_to_sequences([text])
print(text)
word_index = tok.word_index
print('Found %s unique tokens.' % len(word_index))
sequence_pred = sequence.pad_sequences(seqs, maxlen=MAX_SEQUENCE_LENGTH)
print(sequence_pred)
prediction = model.predict(sequence_pred)
print(prediction)
return senti[np.argmax(prediction[0])]
#app.route("/", methods=['GET', 'POST'])
def index():
senti=["furious","angry","angry0","Indiferent","happy","enthusiastic","Euphoric"]
images=['smile.jpg','smile.jpg','smile.jpg','smile.jpg','smile.jpg','smile.jpg','smile.jpg']
lookup_keys = dict(zip(senti, images))
print(request.method)
if request.method == 'POST':
q=request.form['querytext']
prediction=predict(q)
image_path = lookup_keys[prediction] # get the path
return render_template("result.html",
prediction=prediction,
text=q,
image_url=image_path)
return render_template("main.html")
I am not getting any error but the image is not displayed I am not so sure what is wrong, at this moment I am just trying with one image located at the same level of my file called app.py, smile.jpg
$ ls
app.py smile.jpg
Just create a dictionary of your keys and the image values; and use that to return the image for the particular sentiment:
>>> senti=["furious","angry","angry0","Indiferent","happy","enthusiastic","Euphoric"]
>>> images=['home/image0.jpg','home/image1.jpg','home/image2.jpg','home/image3.jpg','home/image4.jpg','home/image5.jpg','home/image6.jpg']
>>> dict(zip(senti, images))
{'enthusiastic': 'home/image5.jpg', 'Indiferent': 'home/image3.jpg', 'furious': 'home/image0.jpg', 'Euphoric': 'home/image6.jpg', 'angry': 'home/image1.jpg', 'happy': 'home/image4.jpg', 'angry0': 'home/image2.jpg'}
>>> lookup_values = dict(zip(senti, images))
>>> lookup_values['angry']
'home/image1.jpg'
You can use this in your view method, to get the right image path and the send it to the template:
#app.route("/", methods=['GET', 'POST'])
def index():
senti=["furious","angry","angry0","Indiferent","happy","enthusiastic","Euphoric"]
images=['home/image0.jpg','home/image1.jpg','home/image2.jpg','home/image3.jpg','home/image4.jpg','home/image5.jpg','home/image6.jpg']
lookup_keys = dict(zip(senti, images))
print(request.method)
if request.method == 'POST':
q=request.form['querytext']
prediction=predict(q)
image_path = lookup_keys[prediction] # get the path
return render_template("result.html",
prediction=prediction,
text=q,
image_url=image_path)
return render_template("main.html")
I am trying to build a prediction web application with Flask. The app should take in user input, process it through a python trained model, then display the results as a chart beside the input form.
My code looks like this:
HTML Form:
<form class = "prediction-options" method = "post" action = "/prediction/results">
<!--the input fields-->
</form>
Flask app.py
#app.route("/")
def main():
return render_template('index.html')
#app.route("/prediction/results", methods = ['POST'])
def predict():
input_aqi = float(request.form['aqi'])/272
input_pm2_5 = float(request.form['pm2_5'])/224
input_pm10 = float(request.form['pm10'])/283
input_so2 = float(request.form['so2'])/36
input_no2 = float(request.form['no2'])/110
input_co = float(request.form['co'])/1.83
input_o3 = float(request.form['o3'])/124
input_list = [[input_aqi,input_pm2_5,input_pm10,input_so2,input_no2,input_co,input_o3]]
output_acute_bronchitis = model_acute_bronchitis.predict(input_list)
output_asthma = model_asthma.predict(input_list)
output_asthmatic_bronchitis = model_asthmatic_bronchitis.predict(input_list)
output_aurti = model_aurti.predict(input_list)
output_bronchitis = model_bronchitis.predict(input_list)
output_pneumonia = model_pneumonia.predict(input_list)
d = collections.OrderedDict()
d['acute_bronchitis'] = output_acute_bronchitis[0]
d['asthma'] = output_asthma[0]
d['asthmatic_bronchitis'] = output_asthmatic_bronchitis[0]
d['aurti'] = output_aurti[0]
d['bronchitis'] = output_bronchitis[0]
d['pneumonia'] = output_pneumonia[0]
prediction = jsonify(d)
return prediction
Right now, I have managed to take in the user input and render the predicted results on the '/prediction/results' page. How can I get the results to show up on the '/' page? I tried to do this:
#app.route("/", methods = ['POST','GET'])
def main():
if request.method == 'POST':
def predict():
#predict function that returns prediction
return render_template('index.html')
But I always get a socket.error: [Errno 32] Broken pipe error message. What should I do?
You can use a session for this, before the last line in your predict route, store the prediction with
session['prediction'] = prediction
and then you can access in any other route in your application, for example you can have this for /
#app.route("/", methods = ['POST','GET'])
def main():
if request.method == 'POST':
pass
prediction = session['prediction']
return render_template('index.html', prediction=prediction)