Reputation: 345
I created a simple ML API using python with flask. It gets data from sample.csv and trains a logistic regression model based on that. I also have a '/predict' endpoint where I can input parameters in for the model to predict.
Example
localhost:80/predict?weight1=1.2&weight2=0.00123&&weight3=0.45
will output { "predicted": 1}
main.py:
from sklearn.linear_model import LogisticRegression
from flask import Flask, request
import numpy as np
# Create Flask object to run
app = Flask(__name__)
@app.route('/')
def home():
return "Predicting status from other features"
@app.route('/predict')
def predict():
# Get values from the server
weight1 = request.args['weight1']
weight2 = request.args['weight2']
weight3 = request.args['weight3']
testData = np.array([weight1, weight2, weight3]).reshape(1, -1)
class_predicted = logisticRegr.predict(testData.astype(float))
output = "{ \"predicted\": " + "\"" + class_predicted[0] + "\"" + "}"
return output
# Train and load the model based on the MetroPCS_Sample
def load_model():
global logisticRegr
label_y = []
label_x = []
with open('sample.csv') as f:
lines = f.readlines()
for line in lines[1:]:
# Adding labels to label_y
label_y.append(int(line[0]))
line = line.strip().split(",")
x_data = []
for e in line[1:]:
# Adding other features to label_x
x_data.append(float(e))
label_x.append(x_data)
train_x = label_x[:700]
train_y = label_y[:700]
test_x = label_x[700:1000]
test_y = label_y[700:1000]
logisticRegr = LogisticRegression()
logisticRegr.fit(train_x, train_y)
predictions = logisticRegr.predict(test_x)
score = logisticRegr.score(test_x, test_y)
# print score
if __name__ == "__main__":
print("Starting Server...")
# Call function that loads Model
load_model()
# Run Server
app.run(host="127.0.0.1", debug=True, port=80)
Everything works well when I run this script without a container.
However, when I placed it in a container and run it, I get the following error:
NameError: global name 'logisticRegr' is not not defined
Dockerfile
FROM tiangolo/uwsgi-nginx-flask:python2.7
# copy over our requirements.txt file
COPY requirements.txt /tmp/
# upgrade pip and install required python packages
RUN pip install -U pip
RUN pip install -r /tmp/requirements.txt
COPY ./app /app
ENV MESSAGE "hello"
requirements.txt
Flask
numpy
sklearn
scipy
Do you know what can cause the NameError when the script is inside a container?
Upvotes: 1
Views: 843
Reputation: 1162
in your def load_model()
. you have global logisticRegr
.
just using global
keyword doesn't make your variable global.
global is used when you want to access and change global variable inside your function. since your logisticRegr
is not global,
when you are trying to access it in def predict()
,
class_predicted = logisticRegr.predict(testData.astype(float))
you would get NameError: global name 'logisticRegr' is not defined
.
now to solve your issue. initialize/declare your logisticRegr
model variable after you initialize your app
variable like this:
# Create Flask object to run
app = Flask(__name__)
logisticRegr = LogisticRegression()
and then remove variable initialization from your load_model
after test_y = label_y[700:1000]
PS : It's recommended to capitalize your global variables. to easily recognize them in your code.
Upvotes: 1