give code for app.py in flask
import tensorflow as tf
import numpy as np
import pandas as pd
import json
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.layers import Input, Embedding, LSTM, Dense, GlobalMaxPooling1D, Flatten
from tensorflow.keras.models import Model,Sequential
import matplotlib.pyplot as plt
import nltk
import random
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Dense,Dropout
with open('data.json', 'r') as f:
    data = json.load(f)

# Preprocess data
lemmatizer = WordNetLemmatizer()
intents = data["intents"]

words = []
classes = []
documents = []

for intent in intents:
    for pattern in intent["patterns"]:
        tokenized = word_tokenize(pattern)
        words.extend(tokenized)
        documents.append((tokenized, intent["tag"]))
        
        if intent["tag"] not in classes:
            classes.append(intent["tag"])

words = [lemmatizer.lemmatize(word.lower()) for word in words if word.isalpha()]
words = sorted(list(set(words)))
classes = sorted(list(set(classes)))

# Create training data
training = []
output_empty = [0] * len(classes)

for document in documents:
    bag = []

    pattern_words = document[0]
    pattern_words = [lemmatizer.lemmatize(word.lower()) for word in pattern_words]

    for word in words:
        bag.append(1) if word in pattern_words else bag.append(0)

    output_row = list(output_empty)
    output_row[classes.index(document[1])] = 1

    training.append([bag, output_row])

random.shuffle(training)
training = np.array(training, dtype=object)

train_x = np.array(list(training[:, 0]))
train_y = np.array(list(training[:, 1]))

# Create model
model = Sequential()
model.add(Dense(128, input_shape=(len(train_x[0]),), activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(64, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(len(train_y[0]), activation="softmax"))

model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

# Train model
model.fit(train_x, train_y, epochs=1000, batch_size=8)

def clean_sentence(sentence):
    sentence_words = word_tokenize(sentence)
    sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
    return sentence_words

def bag_of_words(sentence, vocab):
    sentence_words = clean_sentence(sentence)
    bag = [0] * len(vocab)

    for s in sentence_words:
        for i, word in enumerate(vocab):
            if word == s:
                bag[i] = 1
                
    return np.array(bag)
def chatbot_response(message):
    pred = model.predict(np.array([bag_of_words(message, words)]))[0]
    threshold = 0.25
    pred_class_idx = np.argmax(pred)
    
    if pred[pred_class_idx] > threshold:
        pred_class = classes[pred_class_idx]

        for intent in intents:
            if intent["tag"] == pred_class:
                response = random.choice(intent["responses"])
                return response
    else:
        return "I didn’t understand that. Can you please rephrase?"
while True:
    # Get input from user
    message = input("User: ")

    # Check if user wants to exit
    if message.lower() == "exit":
        print("Chatbot: Goodbye!")
        break

    # Get chatbot's response
    response = chatbot_response(message)

    # Print response
    print("Chatbot:", response)