Python Flask app runs locally, but returns AttributeError when hosted on Heroku
I would try putting
clf = joblib.load('ENS_fitted.joblib')
into a try-except block to see if the exception there is the same as what you're getting at
AttributeError: module '__main__' has no attribute 'FlexibleScaler'
For Example:
try: clf = joblib.load('ENS_fitted.joblib') prediction = clf.predict(features) pred_prob = clf.predict_proba(features)except Exception as e: print(f"Exception: {e}")
Also, I recommend making sure that gunicorn is calling the program as name == "main" by printing out a notice to yourself;
if __name__ == "__main__": print("__name__ is __main__") app.run(debug = True)
If you can't get past the error after doing this, I would look into configuring gunicorn with flask.
It appears that the joblib.save()
that produced ENS_fitted.joblib
happened in flask_start.py
was run directly from python. When that's the case, flask_start
will have a __name__
of "__main__"
. Then, when joblib.save()
pickles, it will save the FlexibleScaler instance as a __main__.FlexibleScaler
.
But when you deploy and run under gunicorn, flask_start
will have a __name__
of "flask_start"
. This confounds joblib.load()
, which expects to find a __main__.FlexibleScaler
, and gives up as you've shown above.
A solution to this is to regenerate your saved model, but this time by invoking flask_start
via
% FLASK_APP=flask_start flask run
then joblib.save()
again, then re-deploy.
Updated
If you're absolutely unable to get the model regenerated, you can try this hack. After the imports in flask_start.py
, add
import __main____main__.FlexibleScalar = FlexibleScalar
You'll either be able to joblib.load()
the model, or you'll run into a similar error with another class, in which case, repeat this trick.