I keep getting this error: "jinja2.exceptions.TemplateNotFound: index.html" - python

i tried to save index.html file in template folder but still it does work. any help would be highly appreciated. here is my code: am using sypder.
#importing neccessary libs
import numpy as np
from flask import Flask,request,render_template
from flask_cors import CORS
import os
import joblib
import pickle
import flask
import newspaper
from newspaper import Article
import urllib
import nltk
nltk.download('punkt')
#loading flash and assigning the model variable
app= Flask(__name__)
CORS(app)
app=flask.Flask(__name__,template_folder='templates')
#handle
with open('model.pk1','rb') as handle:
model= pickle.load(handle)
#app.route('/')
def main():
return render_template('templates/index.html')
#receiving the input url from the user and using web scrapping to
extract th news content
#app.route('/predict',methods=['GET','POST'])
def predict():
url=request.get_data(as_text=True)[5:]
url=urllib.parse.unquote(url)
article=Article(str(url))
article.download()
article.parse()
article.nlp()
news=article.summary
#passing the news article to the model and returning whether it
is Fake or Real
pred=model.predict([news])
return render_template('index.html', prediction_text='The news
is "{}"'.format(pred[0]))
if __name__=="__main__":
port=int(os.environ.get('PORT',5000))
app.run(port=port,debug=True, use_reloader=False)

I'm not sure how is your project structure, but there could be two possible reasons:
This can be changed:
app= Flask(__name__)
CORS(app)
app=flask.Flask(__name__,template_folder='templates')
into:
app= Flask(__name__, template_folder='templates')
CORS(app)
And since you defend the template folder as templates, return render_template('templates/index.html') should change to return render_template('index.html').
Otherwise you're rendering templates/templates/index.html.
Another reason could be the path.
Since it is relative path, do think if it can be ../templates or ../../templates.

Related

Calling method from Flask Blueprint

I am trying to call a get method from my main.py from another python file and I am using flask and blueprints.
I have 2 files: main.py and product.py.
Based on the documentation, I thought after we have done an import, we can then call the method.
In my product.py
import os
from flask import Blueprint, Flask, render_template, request, jsonify
import stripe
import json
import ast
product = Blueprint('product',__name__)
#product.route('/getallproducts', methods=['GET'])
def get_products ():
myList = ["price_1GqLlRFswqvdSoNHi27H2wLV","price_1GqLiAFswqvdSoNHjv4R6scY","price_1GqY8eFswqvdSoNHVSRzEQdn","price_1GqYAcFswqvdSoNH1uReU4kN"]
result =[]
for i in myList:
priceobj = stripe.Price.retrieve(i)
product= stripe.Product.retrieve(priceobj.product)
data = product
data["price"] = priceobj.unit_amount/100
data["priceid"] =i
result.append(data)
return result
In my main.py i have
import os
from flask import Blueprint, Flask, render_template, request, jsonify
import stripe
import json
import ast
from product import product
stripe.api_key = stripe_keys['secret_key']
app=Flask(__name__,template_folder='../client', static_url_path='', static_folder='../client')
app.register_blueprint(product)
#app.route('/', methods=['GET'])
def main():
result =product.get_products()
return render_template('index.html', data=result)
I tried to do product.get_products() but it complained that no such methods exist.
Is there something which I am missing out on as I thought this was the way we can use blueprints?
You're likely getting the invalid method because you're not importing the function get_products() but a variable from your file that uses it. Try changing the import line in your main.py to from product import product, get_products.
Ideally get_products should be a separate method somewhere instead of calling the Flask route method, in this case, you could start off with product.py itself.
def get_all_products():
myList = ["price_1GqLlRFswqvdSoNHi27H2wLV","price_1GqLiAFswqvdSoNHjv4R6scY","price_1GqY8eFswqvdSoNHVSRzEQdn","price_1GqYAcFswqvdSoNH1uReU4kN"]
result =[]
for i in myList:
priceobj = stripe.Price.retrieve(i)
product= stripe.Product.retrieve(priceobj.product)
data = product
data["price"] = priceobj.unit_amount/100
data["priceid"] =i
result.append(data)
and you could simply refer to this method from wherever you need to get all the products.
P.S: Leandro's answer works perfectly if you don't want to follow this method

Retrieving Params from GET request to fetch the value. (PostMan)

From postman, I'm trying to send a GET request with params as Key:
path, Value: home/guest/images/abc.jpeg
I want to retrieve the same and use the Value as the argument of my function.
Somehow I'm unable to get the same, API not being called. Any input shall be helpful.
I'm new to writing REST APIs using Flask Python. I want to get the Value of the Params key: path as the TEST_PATH so that the rest of the code run as it should return the JSONP_data
from flask import Flask
from flask_cors import CORS
import pandas as pd
import datetime
import numpy as np
from flask import jsonify
import json
from pymongo import MongoClient
# set the project root directory as the static folder, you can set others.
app = Flask(__name__)
CORS(app)
counter=0
#app.route('/')
def api_root():
return ('Welcome')
#app.route('/generateTags/<id>', methods=['GET'])
def generateTags1(id):
file = json.loads(create_task(id))
TEST_PATH = file['path']
print(TEST_PATH)
import DenseNet
import Inception
import ResNet
import SqueezNet
from imageai.Prediction import ImagePrediction
prediction = ImagePrediction()
# TEST_PATH = '/home/anit/Documents/Image Analysis/ImageAI-master/Dataset'
dense_list=DenseNet.tag(TEST_PATH, DenseNet.prediction)
dense_list = ['DenseNet'] + dense_list.tolist()[0]
res_list=ResNet.tag(TEST_PATH, ResNet.prediction)
res_list = ['ResNet'] + res_list.tolist()[0]
incept_list=Inception.tag(TEST_PATH, Inception.prediction)
incept_list = ['Inception'] + incept_list.tolist()[0]
squeez_list=SqueezNet.tag(TEST_PATH, SqueezNet.prediction)
squeez_list = ['SqueezNet'] + squeez_list.tolist()[0]
d = {'filename':dense_list[1], 'models':{}}
for l in [dense_list,res_list, incept_list, squeez_list]:
#breakpoint()
d['models'][l[0]] = l[2:]
JSONP_data = jsonify(d)
return JSONP_data
if __name__ == '__main__':
app.run ()

how to get response message when user enters the text using flask?

I created a chatbot using for loop.In browser it is not giving response when user enters the text.
I tried like below:
app.py:
import flask
from flask import Flask, render_template, request
from werkzeug.wrappers import Request, Response
import pandas as pd
import re
#####***** Reading the data
data=pd.read_excel("path",sheet_name='Sheet2')
#######**** Converting columns to a lists
userList=data["User"].tolist()
cbList=data["CB"].tolist()
app = Flask(__name__)
##########***** asking user to enter their questions and giving responses
bot_response=[]
for i in range(0,len(userList)):
user=input("User:")
if user=='':
print("Bye")
break
userReg=re.sub('[^A-Za-z0-9]'," ",user.lower())
userRegSplit=(userReg.split())
ud=str(userList[i]).lower()
ud=re.sub('[^A-Za-z0-9]'," ",ud)
newList=ud.split()
commonWords=[x for x in newList if x in userRegSplit]
if len(commonWords)==len(newList):
bot_response.append(cbList[i])
print(bot_response)
#app.route('/')
def CBApp():
return render_template('CBApp.html')
#app.route("/get")
def get_bot_response():
userText = request.args.get('msg')
return str(bot_response.get_response(userText))
if __name__=='__main__':
from werkzeug.serving import run_simple
app.debug=True
run_simple('localhost',port,app)
html template will look like below:
[1]: https://i.stack.imgur.com/rY4tW.png
suggest me where am gone wrong?

Parse result into JSON using Python and Flask

Now, I managed to successfully pull basic information from my smart device onto the terminal using pyHS100 on python (v3.6) using the following code
from pyHS100 import SmartPlug
from pprint import pformat as pf
plug = SmartPlug("10.xxx.xxx.xxx")
print("Hardware: %s" % pf(plug.hw_info))
which results in the following:
but I can't parse the data into json format and display it on the local server for my RESTful API purpose if I done it this way:
from flask import Flask, jsonify
from flask_restful import Resource, Api
from pyHS100 import SmartPlug
app = Flask(__name__)
#app.route('/api')
def get():
plug = SmartPlug("10.xxx.xxx.xxx")
sys = plug.hw_info
return jsonify({'data':sys})
if __name__ == '__main__':
app.run(host='0.0.0.0')
app.run(debug=True)
All I need is for the information to be presented into something like this:
What did I do wrong and how do I this fix? Thanks
I believe the best way to solving this is by using json.dumps

How to pass HTML form data stored in a variable to a Python script in Flask?

I am building a data product (an NLP chat application) for which I am learning Flask so that the user can have a better UI to interact with my product.
I have written down the following code in Flask to get the user input and stored it in a variable.
main.py
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('init.html')
#app.route('/handle_data', methods = ['POST', 'GET'])
def handle_data():
userQuestion = request.form['userQuestion']
print(userQuestion)
return render_template('init.html', userQuestion = userQuestion)
if __name__ == '__main__':
app.run()
init.html
<!DOCTYPE HTML>
<html>
<body>
<form action="{{ url_for('handle_data') }}" method="post">
<input type="text" name="userQuestion">
<input type="submit">
</form>
</body>
</html>
I've handled the form data and stored it in a variable userQuestion. I want to pass this variable to another python script which contains the code of my training model.
doc2vec_main.py
import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
ps = PorterStemmer()
sentence0 = models.doc2vec.LabeledSentence(words=[u'sampling',u'what',u'is',u'sampling'],tags=["SENT_0"])
sentence1 = models.doc2vec.LabeledSentence(words=[u'sampling',u'tell',u'me',u'about',u'sampling'],tags=["SENT_1"])
sentence2 = models.doc2vec.LabeledSentence(words=[u'elig',u'what',u'is',u'my',u'elig'],tags=["SENT_2"])
sentence3 = models.doc2vec.LabeledSentence(words=[u'eligiblity',u'limit', u'what',u'is',u'my'],tags=["SENT_3"])
sentence4 = models.doc2vec.LabeledSentence(words=[u'eligiblity',u'claim',u'how',u'much',u'can',u'I'],tags=["SENT_4"])
sentence5 = models.doc2vec.LabeledSentence(words=[u'retir',u'eligibility',u'claim',u'i',u'am',u'how',u'much',u'can',u'i'],tags=["SENT_5"])
# ... list of all the training set.
# User inputs a question
document = input("Ask a question:")
tokenized_document = list(gensim.utils.tokenize(document, lowercase = True, deacc = True))
stemmed_document = []
for w in tokenized_document:
stemmed_document.append(ps.stem(w))
sentence19 = models.doc2vec.LabeledSentence(words= stemmed_document, tags=["SENT_19"])
sentences = [sentence0,sentence1,sentence2,sentence3, sentence4, sentence5,sentence6, sentence7, sentence8, sentence9, sentence10, sentence11, sentence12, sentence13, sentence14, sentence15, sentence16, sentence17, sentence18, sentence19]
model = models.Doc2Vec(size=4, alpha=0.25, min_alpha=.025, min_count=1)
model.build_vocab(sentences)
for epoch in range(30):
model.train(sentences, total_examples=model.corpus_count, epochs =
model.iter)
model.alpha -= 0.002
model.min_alpha = model.alpha
model.save("my_model.doc2vec")
model_loaded = models.Doc2Vec.load('my_model.doc2vec')
print (model.docvecs.most_similar(["SENT_19"]))
My problem is I cannot find a way to connect doc2vec_main.py to main.py and pass the value of userQuestion to the document variable in doc2main.py
script. That is when a user inputs a question in the form and clicks submit, the value of the form get passed down to document in doc2vec_main.py and the remaining script runs.
I have searched a lot on the internet but it didn't help. Can you suggest me a way to do it? I'm a complete beginner in Flask so forgive me for any mistake.
I found a possible solution.
In your python script file import sys
when you run your script like this -> python doc2vec_main.py "question here"
you can access that variable through
>>> import sys
>>> print(sys.argv)
>>>['doc2vec_main.py', 'question here']
So then you can simply use this
document = sys.argv[1]
Okay we found the manuall way but you need to automate this with flask.
Inside flask app import os
and then when you want to execute your externall script do this
os.system("python doc2vec_main.py %s") % request.form['userQuestion']
You know this will work but wouldnt it be better to do this in one app only? it would be better.
import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
ps = PorterStemmer()
# load the model here
model_loaded = models.Doc2Vec.load('my_model.doc2vec')
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('init.html')
#app.route('/handle_data', methods = ['POST', 'GET'])
def handle_data():
userQuestion = request.form['userQuestion']
print(userQuestion)
q_vector = doc2vec_main(userQuestion)
return render_template('init.html', userQuestion = userQuestion)
def doc2vec_main(document):
"""whatever you want to do with your pre-trained doc2vec model can go here. I assume that doc2vec_main meant to return vector for a given document. for training part of the code you should write a separate function."""
# your code here!
return "replace this with your vector"
if __name__ == '__main__':
app.run()
Put the script in another module of your Flask application, under a function that takes as argument the variable you want to process:
import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
def doc2vec(user_question):
# your code here...
In your handle_data Flask view just pass the value from the form to your function. Take into consideration that this could not work in case your function is expensive so you can't wait for the result during normal request/response http flow.

Categories