I am currently stuck trying to load a model to make a prediction and load the result into an API endpoint. I have this code, which contains the model and saves the model as a pickle file.
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pickle
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#KMeans
km = KMeans(n_clusters=3)
km.fit(X)
km.predict(X)
labels = km.labels_#Plotting
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
c=labels.astype(np.float), edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("K Means", fontsize=14)
with open('C:\\Users\\ryans\\kmeans.pkl', 'wb') as f:
pickle.dump(km, f)
This seems to work fine, but the last two lines, to pickle the file and save it, seems necessary ONLY the first time it is run. If I open the file, using the code below, I don't see the need to re-save the picked file. Anyway, here is the code that I am testing, to hit the API endpoint.
from flask import Flask, jsonify
import pickle
import pandas as pd
import requests
api = Flask(__name__)
#api.route('/predict', methods=['POST'])
def predict():
json_features = requests.json
query_df = pd.DataFrame(json_features)
features = pd.get_dummies(query_df)
prediction = kmeans.predict(features)
return jsonify({'prediction': list(prediction)})
if __name__ == '__main__':
try:
kmeans = pickle.load(open("C:\\Users\\ryans\\kmeans.pkl", "rb"))
api.run(debug=True, port=8000)
traceback.print_exc(file=sys.stdout)
except:
print("Exception in user code:")
print('-'*60)
traceback.print_exc(file=sys.stdout)
print('-'*60)
When I run that code, I get this error.
* Serving Flask app "untitled41" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Restarting with windowsapi reloader
Exception in user code:
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython-input-48-1749e4d56106>", line 19, in <module>
api.run(debug=True, port=8000)
File "C:\Users\ryans\Anaconda3\lib\site-packages\flask\app.py", line 990, in run
run_simple(host, port, self, **options)
File "C:\Users\ryans\Anaconda3\lib\site-packages\werkzeug\serving.py", line 1050, in run_simple
run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
File "C:\Users\ryans\Anaconda3\lib\site-packages\werkzeug\_reloader.py", line 339, in run_with_reloader
sys.exit(reloader.restart_with_reloader())
SystemExit: 1
------------------------------------------------------------
It's probably easier here to modify my original post with my findings, based on what you suggested.
I added this:
api.run(debug=True, port=8000, use_reloader=False)
Now, I go to my browser and enter this: 'http://localhost:8000/predict'
I see this result:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I tested a very simple sample script:
from flask import Flask
app = Flask(__name__)
#app.route('/api', methods=['GET','POST','DELETE'])
def api():
return 'YOU MADE IT!'
if __name__ == '__main__':
app.run(debug=True, port=8000, use_reloader=False)
This works totally fine for me!
Finally, I don't understand this part:
export FLASK_APP=my_app.py
export FLASK_DEBUG=1
flask run
Does this go at the end of the 'kmeans.py' script? When I add that, I get 'Invalid Syntax' on the first of the three lines.
I assume that you are using the flask code in notebook (Ipython environment) and debug=True is forcing the process to reload, which is causing this issue, you can set use_reload to False
api.run(debug=True, port=8000, use_reloader=False)
Also, try to run it in a script with flask command (from command line /console) instead by first save the code in a file (for e.g app.py) and setting the script name and debug mode as below
export FLASK_APP=my_app.py
export FLASK_DEBUG=1
flask run
Related
I'm building a python visualization application. I'm using 2 modules for this:
LUX
Pandas Profiling
The above 2 are auto visualization libraries that take in a csv/xlsx file & give descriptive statistics of the data which includes visualizations.
LUX has a customizable function called 'Intent' which analyzes the relationship among specific variables upon selection.
The visualizations get stored in a HTML file on my local system.
What I have tried:
This is my Python code for the visualization:
# Importing libraries
import csv
from mimetypes import init
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import os
import csv
import json
from pandas_profiling import ProfileReport
import pandas_profiling as pp
import lux
# # Pandas profiling
def pand_prof_fun(eda_file, savepath):
profile = ProfileReport(eda_file)
# Activating the widgets
profile.to_widgets()
profile.to_notebook_iframe()
# Saving & generating the report
pp.ProfileReport(eda_file)
profile.to_file(savepath)
profile = ProfileReport(eda_file, title="My Data Profile Report")
return profile
def lux_vis(eda_file, vis_file_path, vis_file_path_intent, intent_list):
eda_file.save_as_html(vis_file_path)
# Visualizing selected variables
eda_file.intent = intent_list
eda_file.save_as_html(vis_file_path_intent)
def run(csv_filepath, int_list):
csv_dataframe = pd.read_csv(csv_filepath)
os.makedirs(r'templates', exist_ok=True)
pand_prof_path = r'templates\pandas_prof.html'
lux_save_path = r'templates\lux_complete.html'
lux_intent_save_path = r'templates\lux_intent.html'
pand_prof_fun(csv_dataframe, pand_prof_path)
lux_vis(csv_dataframe, lux_save_path, lux_intent_save_path, int_list)
if __name__ == '__main__':
csv_filepath = r'C:\Users\projects\Churn_bank.csv'
I now want to build a Flask API such that the user can choose what they want to display, i.e., -->
Lux - displays the pairwise relationship between all variables. (or)
Lux using intent (Customization)- displays the relationship between specified variables. (or)
Pandas Profiling - displays the descriptive statistics of the entire data.
This is my API code for the 2nd module (Lux using intent):
from flask import Flask, render_template
import requests
from flask import Flask, request, jsonify
import json
import traceback
from visualization_function import run
from visualization_function import lux_vis
from visualization_function import pand_prof_fun
app = Flask(__name__)
#app.route('/visualization_with_us', methods = ['POST'])
def home1():
allowed_extensions = ['csv', 'xlsx']
file = request.json.get('filepath')
filename=file.split("/")[-1]
intents = request.json.get('intents')
file_extension = filename.split('.', 1)[1].lower()
try:
if file_extension in allowed_extensions:
run(file, intents)
return "Successful"
else:
return "File not supported"
except:
return "Exception in file"
if __name__ == '__main__':
app.run()
Entering input via 'Postman'
Entering the 'intents' via postman returns "successful" message & gives the right output. The HTML file gets created & saved in my "templates" folder. But when I try to include the other two modules in my API code - 'Module 1' & 'Module 3', my code doesn't work.
Here's how I've included 'Module 1' & 'Module 3' in my API code. My idea is to create a list of the modules & depending on the module chosen, the respective module/function runs -->
from flask import Flask
from flask import Flask, request
from importlib.util import module_from_spec
from flask import Flask, render_template
import requests
from flask import Flask, request, jsonify
import json
import traceback
from visualization_function import run
from visualization_function import lux_vis
from visualization_function import pand_prof_fun
app = Flask(__name__)
#app.route('/visualization_with_apoorva', methods = ['POST'])
def home1():
allowed_extensions = ['csv', 'xlsx']
available_modules=['pandas_profiling', 'lux_overall', 'lux_intent']
file = request.json.get('filepath')
filename=file.split("/")[-1]
file_extension = filename.split('.', 1)[1].lower()
intents = request.json.get('intents')
module_selection= request.json.get('module')
try:
if file_extension in allowed_extensions:
return lux_vis()
if module_selection=='lux_intent':
intents = request.json.get('intents')
run(file, intents)
if module_selection=='lux_overall':
run(file, lux_vis)
if module_selection=='pandas_profiling':
run(file, pand_prof_fun)
return "Successful"
else:
return "File not supported"
except:
return "Exception in file"
if __name__ == '__main__':
app.run()
Error: When I run the route on postman it returns "Exception in file" message.
Postman output
What is the error in my code? How do I include 'module 1' & 'module 3' in the same Flask API code such that the user can choose any one among the 3 modules & get the desired output?
I'm running this code to train a dimple model and pickle the results:
import pandas as pd
df = pd.read_csv('C:\\Users\\ryans\\Desktop\\prices.csv')
df.head()
y = df['Value']
X = df[['Rooms', 'Distance']]
from sklearn import linear_model
lm = linear_model.LinearRegression()
lm.fit(X, y)
lm.predict([[8.2,9]])
import pickle
pickle.dump(lm, open('C:\\Users\\ryans\\Desktop\\model.pkl','wb'))
Now, I open Anaconda Prompt, and run the file: C:\Users\ryans\Desktop\app.py.
Here's the app.py code:
from flask import Flask, request, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open('C:\\Users\\ryans\\Desktop\\model.pkl', 'rb'))
#app.route('/')
def home():
return render_template('index.html')
#app.route('/predict',methods=['POST'])
def predict():
"""Grabs the input values and uses them to make prediction"""
rooms = int(request.form["rooms"])
distance = int(request.form["distance"])
prediction = model.predict([[rooms, distance]]) # this returns a list e.g. [127.20488798], so pick first element [0]
output = round(prediction[0], 2)
return render_template('index.html', prediction_text=f'A house with {rooms} rooms and located {distance} meters from the city center has a value of ${output}')
if __name__ == "__main__":
app.run()
Here is the traceback:
Traceback (most recent call last):
File "C:\Users\ryans\Desktop\app.py", line 2, in <module>
from flask import Flask, request, render_template
ModuleNotFoundError: No module named 'flask'
Flask is already installed, so I think it's some kind of issue like running Flask in a virtual environment, or whatever. This is my first time doing this kind of thing. How can I get Flask to run on Windows?
How did you install flask? If you're running under the conda prompt, try running conda install flask. And then see if it allows you to run your application
from flask import Flask,request, url_for, redirect, render_template
import pickle
import numpy as np
app = Flask(__name__)
model=pickle.load(open('model.pkl','rb'))
#app.route('/')
def hello_world():
return render_template("nikit.html")
// I want to run ipynb file so that it can get refreshed and show new output everytime.
#app.route('/predict',methods=['POST'])
def predict():
int_features=[int(x) for x in request.form.values()]
final=[np.array(int_features)]
prediction=model.predict(final)
return render_template('nikit.html',pred = float(prediction*10000) )
if __name__ == '__main__':
app.run(debug=True)
I want to run ipynb file so that it can get refreshed and show new output everytime.
i am working in machine learning model and what I want is my ipynb model to run everytime when I open file web page.
I have written my 1st Python API project with Flask and now am trying to deploy it to Netlify.
Searched online and found I need to use Flask-Frozen to generate a static website.
Not sure I'm doing it correctly, because my project is a API project not a website project, so may be I should not use Flask-Frozen(FF)?
But if I could still use FF to generate static website for my API project, here is my project:
--
app.py
mazesolver
mazeapi.py
Here is the app.py
from flask_frozen import Freezer
from mazesolver import mazeapi
# Call the application factory function to construct a Flask application
# instance using the development configuration
# app = mazeapi()
# Create an instance of Freezer for generating the static files from
# the Flask application routes ('/', '/breakfast', etc.)
freezer = Freezer(mazeapi)
if __name__ == '__mazeapi__':
# Run the development server that generates the static files
# using Frozen-Flask
freezer.run(debug=True)
mazeapi.py
import io
from mazesolver.solver import MazeSolver
from markupsafe import escape
from flask import Flask, flash, request, redirect, send_file
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = { 'png', 'jpg', 'jpeg' }
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
#app.route('/maze/<mazename>')
def maze(mazename):
return 'maze 4 %s' % escape(mazename)
Whenever I run:
python app.py
I got this error:
Traceback (most recent call last):
File "app.py", line 10, in <module>
freezer = Freezer(mazeapi)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 98, in __init__
self.init_app(app)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 108, in init_app
self.url_for_logger = UrlForLogger(app)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 588, in __init__
self.app.url_default_functions.setdefault(None, []).insert(0, logger)
AttributeError: module 'mazesolver.mazeapi' has no attribute 'url_default_functions'
I had the same issue and added
url_default_functions={}
to the app, right before
if __name__ == "__main__":
app.run()
I guess you could put it right after
app = Flask(__name__)
and the error went way... but there are many more :) It seems that frozen-flask isn't working with the lastest flask, but I couldn't get any other versions working with it.
Did you manage to get it working?
You have a simple namespace bug.
In the code you've posted, you are freezing your module mazeapi, not the actual Flask application, mazeapi.app.
Try changing your Freezer call in line 10 of app.py to:
freezer = Freezer(mazeapi.app)
I am trying to set up a Flask web app using Elastic Beanstalk on AWS. I have followed the tutorial here and that works fine. I am now looking to expand the Flask webapp, and this works fine, until I import scipy.spatial as spatial, when this is part of my import statements, running eb open just times out. I receive
>>>> HTTP ERROR 504
running the webapp locally works absolutely fine even with the scipy import, it is only when I try and deploy to beanstalk that it doesn't want to work. Below is my code
import os
import requests
from bs4 import BeautifulSoup
import pandas as pd
import scipy.spatial as spatial ##### Removing this and everything works!
from flask import Flask
from flask_cors import CORS
from flask_restful import Resource, Api
from flask_jsonpify import jsonify
# print a nice greeting.
def say_hello(username = "World"):
df = pd.DataFrame({"a":[1,2,3]})
return '<p>Hello %s!</p>\n' % username
# some bits of text for the page.
header_text = '''
<html>\n<head> <title>EB Flask Test</title> </head>\n<body>'''
instructions = '''
<p><em>Hint</em>: This is a RESTful web service! Append a username
to the URL (for example: <code>/Thelonious</code>) to say hello to
someone specific.</p>\n'''
home_link = '<p>Back</p>\n'
footer_text = '</body>\n</html>'
# EB looks for an 'application' callable by default.
application = Flask(__name__)
# add a rule for the index page.
application.add_url_rule('/', 'index', (lambda: header_text +
say_hello() + instructions + footer_text))
# add a rule when the page is accessed with a name appended to the site
# URL.
application.add_url_rule('/<username>', 'hello', (lambda username:
header_text + say_hello(username) + home_link + footer_text))
# run the app.
if __name__ == "__main__":
# Setting debug to True enables debug output. This line should be
# removed before deploying a production app.
application.debug = True
application.run()
I have tried increasing the command timeout for the environment from 600 to 900, although the timeout error occurs well before 600 seconds has elapsed.
Right, I am not sure why this is the case but I updated the version of scipy in my requirements.txt and the app is working as expected!
Originally I had
scipy==1.4.1
Now I have
scipy==1.2.3
I have no idea why this has fixed the deployment issue, especially given 1.4.1 works perfectly locally. If anyone has an idea, or if this a bug I should be reporting it would be good to know!