Manas Bisht
Manas Bisht

Reputation: 21

AttributeError: Can't get attribute 'TextPreprocessor', when deploying Flask app on Render

The problem is I have a flask app, which predict spam or ham text, by taking input from user. I have two 'joblib' models with pipelines for text preprocessing and prediction (with tensorflow)

This is my app.py

from flask import Flask, render_template,request, jsonify
import joblib
import os
import pickle
from pipe_classes import TextPreprocessor, KerasClassifier

app = Flask(__name__)

@app.route("/") # Site end
def hello():

    return render_template("index.html")


@app.route("/predict", methods=['POST', 'GET'])
def predict():
   
    data = request.get_json()
    text = data.get('inputText')
    
    if text != None:
        print(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'))

        with open(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'), 'rb') as f:
            preprocess = pickle.load(f)

        # preprocess = joblib.load(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'))
        # model = joblib.load(os.path.join(os.path.dirname(__file__), 'Models', 'spam-ham-pipe.joblib'))

        with open(os.path.join(os.path.dirname(__file__), 'Models', 'spam-ham-pipe.joblib'), 'rb') as f:
            model = pickle.load(f)

        ans = model.predict(preprocess.transform([text]))

        ans = ans[0]

    else:
        ans=""

    # return render_template("index.html", answer=ans)
    return jsonify({'answer': ans}) 

if __name__ == "__main__":
    
    from pipe_classes import TextPreprocessor, KerasClassifier
    app.run(debug=True)

And these are the classes it takes for pipeline to load pipe_classes.py

from sklearn.base import TransformerMixin, BaseEstimator, ClassifierMixin
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np


class TextPreprocessor(BaseEstimator, TransformerMixin):
        def __init__(self, max_vocab_size=20000, max_len=None):
            self.max_vocab_size = max_vocab_size
            self.max_len = None
            self.tokenizer = Tokenizer(num_words=self.max_vocab_size)
        
        def fit(self, X, y=None):
            print("Text: ", X)
            self.tokenizer.fit_on_texts(X)
            self.word_index = self.tokenizer.word_index
            self.max_len = len(self.word_index)
            self.vocab_size = len(self.word_index)
            if self.max_len is None:
                self.max_len = max(len(seq) for seq in self.tokenizer.texts_to_sequences(X))
            return self
        
        def transform(self, X, y=None):
            print("Inside tranform function")
            seqs = self.tokenizer.texts_to_sequences(X)
            X_padded = pad_sequences(seqs, maxlen=self.max_len)
            print("X_padded: ", X_padded)
            return X_padded



class KerasClassifier(BaseEstimator, ClassifierMixin):
        def __init__(self, model):
            self.model = model
        
        def fit(self, X, y):
            print("Inside Keras Clasifier fit")
            # Next time I will do training of model here
            return self 

        def label(self, predictions):
            # ans = ["Spam" if pred_i[0]==1 else "Ham" for pred_i in predictions]
            ans = []
            print("Inside label")
            for pred_i in predictions:
                print(pred_i)
                if pred_i == 1:
                    ans.append("Spam")
                else:
                    ans.append("Ham")
                    
            return ans
        
        def predict(self, X):
            print(X)
            predictions = self.model.predict(X)
            pred = (predictions >= 0.5).astype(int)
            print("Predictions: ", predictions)
            return self.label(pred)



Problem:

When I am running app.py, in local system its giving correct output, but as soon as i deployed the whole site in Render,

But when I input some text, it shows this error:

AttributeError: Can't get attribute 'TextPreprocessor' on <module '__main__' from '/opt/render/project/src/.venv/bin/gunicorn'>

Seems like it can't find TextPreprocessor class, when i used these classes in app.py same issue occured..

I am stuck in this issue

Upvotes: 1

Views: 24

Answers (0)

Related Questions