title: Why does my Flask app work when executing using `python app.py` but not when using `heroku local web` or `flask run`?
body: <p>I wrote a Flask-based web app that takes text from users and returns the probability that it is of a given classification (full script below). The app loads some of the trained models needed to make predictions before any requests are made. I am currently trying to deploy it on Heroku and experiencing some problems.</p>
  
  <p>I am able to run it locally when I execute <code>python ml_app.py</code>. But when I use the Heroku CLI command <code>heroku local web</code> to try to run it locally to test before deployment, I get the following error</p>
  
  <blockquote>
    <p>AttributeError: module '__main__' has no attribute 'tokenize'</p>
  </blockquote>
  
  <p>This error is associated with the loading of a text vectorizer called TFIDF found in the line </p>
  
  <pre><code>tfidf_model = joblib.load('models/tfidf_vectorizer_train.pkl')
  </code></pre>
  
  <p>I have imported the required function at the top of the script to ensure that this is loaded properly (<code>from utils import tokenize</code>). This works given that I can run it when I use <code>python ml_app.py</code>. But for reasons I do not know, it doesn't load when I use <code>heroku local web</code>. It also doesn't work when I use the Flask CLI command <code>flask run</code> when trying to run it locally. Any idea why?</p>
  
  <p>I admit that I do not have a good understanding of what is going on under the hood here (with respect to the web dev./deployment aspect of the code) so any explanation helps.</p>
  
  <pre><code>from flask import Flask, request, render_template
  from sklearn.externals import joblib
  from utils import tokenize  # custom tokenizer required for tfidf model loaded in load_tfidf_model()
  
  app = Flask(__name__)
  
  models_directory = 'models'
  
  
  @app.before_first_request
  def nbsvm_models():
  
      global tfidf_model
      global logistic_identity_hate_model
      global logistic_insult_model
      global logistic_obscene_model
      global logistic_severe_toxic_model
      global logistic_threat_model
      global logistic_toxic_model
  
      tfidf_model = joblib.load('models/tfidf_vectorizer_train.pkl')
      logistic_identity_hate_model = joblib.load('models/logistic_identity_hate.pkl')
      logistic_insult_model = joblib.load('models/logistic_insult.pkl')
      logistic_obscene_model = joblib.load('models/logistic_obscene.pkl')
      logistic_severe_toxic_model = joblib.load('models/logistic_severe_toxic.pkl')
      logistic_threat_model = joblib.load('models/logistic_threat.pkl')
      logistic_toxic_model = joblib.load('models/logistic_toxic.pkl')
  
  
  @app.route('/')
  def my_form():
      return render_template('main.html')
  
  
  @app.route('/', methods=['POST'])
  def my_form_post():
      """
          Takes the comment submitted by the user, apply TFIDF trained vectorizer to it, predict using trained models
      """
  
      text = request.form['text']
  
      comment_term_doc = tfidf_model.transform([text])
  
      dict_preds = {}
  
      dict_preds['pred_identity_hate'] = logistic_identity_hate_model.predict_proba(comment_term_doc)[:, 1][0]
      dict_preds['pred_insult'] = logistic_insult_model.predict_proba(comment_term_doc)[:, 1][0]
      dict_preds['pred_obscene'] = logistic_obscene_model.predict_proba(comment_term_doc)[:, 1][0]
      dict_preds['pred_severe_toxic'] = logistic_severe_toxic_model.predict_proba(comment_term_doc)[:, 1][0]
      dict_preds['pred_threat'] = logistic_threat_model.predict_proba(comment_term_doc)[:, 1][0]
      dict_preds['pred_toxic'] = logistic_toxic_model.predict_proba(comment_term_doc)[:, 1][0]
  
      for k in dict_preds:
          perc = dict_preds[k] * 100
          dict_preds[k] = "{0:.2f}%".format(perc)
  
      return render_template('main.html', text=text,
                             pred_identity_hate=dict_preds['pred_identity_hate'],
                             pred_insult=dict_preds['pred_insult'],
                             pred_obscene=dict_preds['pred_obscene'],
                             pred_severe_toxic=dict_preds['pred_severe_toxic'],
                             pred_threat=dict_preds['pred_threat'],
                             pred_toxic=dict_preds['pred_toxic'])
  
  
  if __name__ == '__main__':
  
      app.run(debug=True)
  </code></pre>