Python Flask app runs locally, but returns AttributeError when hosted on Heroku Python Flask app runs locally, but returns AttributeError when hosted on Heroku flask flask

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.