I provided the mandatory code below like flask app, predictionmodel.py and html code still I don't know what the problem is. whenever I run on localhost after clicking submit, I am getting error
The browser (or proxy) sent a request that this server could not understand.
Flask Application Server
from flask import Flask, jsonify, request, render_template
from predictionModel import PredictionModel
import pandas as pd
from random import randrange
app = Flask(__name__, static_folder="./static",
template_folder="./templates")
@app.route("/")
def home():
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
data = request.json
model = PredictionModel(data)
result = model.predict()
return jsonify(result)
if __name__ == '__main__':
app.run()
Prediction Model Code
import timeit
from nltk.stem import WordNetLemmatizer
from nltk import pos_tag
from nltk.corpus import stopwords
from nltk.corpus import wordnet
import pickle as pickle
import pickle
import string
import nltk
nltk.data.path.append('./nltk_data')
start = timeit.default_timer()
with open("pipeline.pkl", 'rb') as f:
pipeline = pickle.load(f)
stop = timeit.default_timer()
print('=> Pickle Loaded in: ', stop - start)
class PredictionModel:
output = {}
def __init__(self, text):
self.output['original'] = text
def predict(self):
self.preprocess()
self.pos_tag_words()
clean_and_pos_tagged_text = self.output['preprocessed'] + \
' ' + self.output['pos_tagged']
self.output['prediction'] = 'FAKE' if pipeline.predict(
[clean_and_pos_tagged_text])[0] == 0 else 'REAL'
return self.output
def preprocess(self):
text = self.output['original'].lower()
text = [t for t in text.split(" ") if len(t) > 1]
text = [word for word in text if not any(c.isdigit() for c in word)]
text = [word.strip(string.punctuation) for word in text]
stop = stopwords.words('english')
text = [x for x in text if x not in stop]
text = [t for t in text if len(t) > 0]
pos_tags = pos_tag(text)
text = [WordNetLemmatizer().lemmatize(t[0], self.get_wordnet_pos(t[1]))
for t in pos_tags]
self.output['preprocessed'] = " ".join(text)
def get_wordnet_pos(self, pos_tag):
if pos_tag.startswith('J'):
return wordnet.ADJ
elif pos_tag.startswith('V'):
return wordnet.VERB
elif pos_tag.startswith('N'):
return wordnet.NOUN
elif pos_tag.startswith('R'):
return wordnet.ADV
else:
return wordnet.NOUN
def pos_tag_words(self):
pos_text = nltk.pos_tag(
nltk.word_tokenize(self.output['preprocessed']))
self.output['pos_tagged'] = " ".join(
[pos + "-" + word for word, pos in pos_text])
And following is the HTML code
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="https://unpkg.com/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<title>Hello, world!</title>
</head>
<body>
<header class="text-gray-600 body-font -my-10">
<div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
<a class="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-10 h-10 text-white p-2 bg-purple-500 rounded-full" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
</svg>
<span class="ml-3 text-xl">Fake News Detection</span>
</a>
<nav class="md:ml-auto flex flex-wrap items-center text-base justify-center">
<a class="mr-5 hover:text-gray-900">Home</a>
<a class="mr-5 hover:text-gray-900">Contact us</a>
<a class="mr-5 hover:text-gray-900">About us</a>
</nav>
</div>
</header><hr>
<section class="text-gray-600 body-font">
<div class="container px-5 py-24 mx-auto">
<div class="flex flex-col text-center w-full mb-20">
<h2 class="text-xs text-indigo-500 tracking-widest font-medium title-font mb-1">MACHINE LEARNING PROJECT</h2>
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">Fake News Detection</h1>
<p class="lg:w-2/3 mx-auto leading-relaxed text-base">It is an easy tool to detect whether your input news is real or fake.</p>
</div>
<div class="center">
<form action="/predict" method="POST">
<div class="form-group">
<label for="exampleInputEmail1">Enter News</label>
<input type="text" class="form-control" id="news" name="news" aria-describedby="emailHelp" placeholder="Enter news">
<small id="emailHelp" class="form-text text-muted">Thankyou for using our product</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</section>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html
The problem is in your predict route you defined in the Flask application.
The main problem is you are getting data by using request.json which is only valid if you are posting a valid json .e.g your app will work if i post the news like below
Notice the Content Type as
application/json, but when you post the same thing from your html code the Content Type istext/htmlwhich flask parses in to the form attribute so to fix the error you need to change "request.data" to "request.form['news']" e.g. your update post endpoint would be