NanobotzAI commited on
Commit
bf5d856
·
verified ·
1 Parent(s): a3dcdff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -35
app.py CHANGED
@@ -11,29 +11,38 @@ app = Flask(__name__, template_folder=os.getcwd())
11
 
12
  # Default settings
13
  class ChatConfig:
14
- MODEL = "google/gemma-3-27b-it"
15
  DEFAULT_SYSTEM_MSG = "You are an AI assistant answering only based on the uploaded PDF."
16
  DEFAULT_MAX_TOKENS = 512
17
  DEFAULT_TEMP = 0.3
18
  DEFAULT_TOP_P = 0.95
19
 
20
- client = InferenceClient(ChatConfig.MODEL)
 
 
 
 
 
21
  embed_model = SentenceTransformer("all-MiniLM-L6-v2", cache_folder="/tmp")
22
  vector_dim = 384 # Embedding size
23
  index = faiss.IndexFlatL2(vector_dim) # FAISS index
24
 
25
  documents = [] # Store extracted text
26
 
27
- def extract_text_from_pdf(pdf_path):
28
- """Extracts text from PDF"""
29
- doc = fitz.open(pdf_path)
30
  text_chunks = [page.get_text("text") for page in doc]
 
31
  return text_chunks
32
 
33
  def create_vector_db(text_chunks):
34
  """Embeds text chunks and adds them to FAISS index"""
35
  global documents, index
36
-
 
 
 
37
  documents = text_chunks
38
  embeddings = embed_model.encode(text_chunks)
39
 
@@ -70,52 +79,63 @@ def generate_response(
70
 
71
  context = search_relevant_text(message) # Get relevant content from PDF
72
 
73
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
74
  for user_msg, bot_msg in history:
75
- if user_msg:
76
  messages.append({"role": "user", "content": user_msg})
77
- if bot_msg:
78
  messages.append({"role": "assistant", "content": bot_msg})
79
 
80
- messages.append({"role": "user", "content": f"Context: {context}\nQuestion: {message}"})
81
-
82
- response = ""
83
- for chunk in client.chat_completion(
84
- messages,
85
- max_tokens=max_tokens,
86
- stream=True,
87
- temperature=temperature,
88
- top_p=top_p,
89
- ):
90
- token = chunk.choices[0].delta.content or ""
91
- response += token
92
- return response
93
-
 
 
94
  @app.route('/')
95
  def index():
96
  """Serve the HTML page for the user interface"""
97
  return render_template('index.html')
98
 
99
- UPLOAD_FOLDER = "/tmp/uploaded_files"
100
- os.makedirs(UPLOAD_FOLDER, exist_ok=True) # Ensure the folder exists
101
-
102
  @app.route('/upload_pdf', methods=['POST'])
103
  def upload_pdf():
104
  """Handle PDF upload"""
105
  if 'pdf' not in request.files:
106
- return jsonify({"error": "No file part"}), 400 # Handle missing file
107
 
108
  file = request.files['pdf']
109
  if file.filename == "":
110
- return jsonify({"error": "No selected file"}), 400 # Handle empty filename
111
-
112
- pdf_path = os.path.join(UPLOAD_FOLDER, file.filename)
113
 
114
  try:
115
- file.save(pdf_path) # Save the uploaded PDF
116
-
117
- # Extract text and create vector database
118
- text_chunks = extract_text_from_pdf(pdf_path)
 
 
 
 
 
 
 
 
 
119
  create_vector_db(text_chunks)
120
 
121
  return jsonify({"message": "PDF uploaded and indexed successfully!"}), 200
@@ -128,7 +148,7 @@ def ask_question():
128
  message = request.json.get('message')
129
  history = request.json.get('history', [])
130
  response = generate_response(message, history)
131
- return jsonify({"response": response})
132
 
133
  if __name__ == '__main__':
134
  app.run(debug=True)
 
11
 
12
  # Default settings
13
  class ChatConfig:
14
+ MODEL = "google/gemma-3-27b-it" # Change back to Gemma
15
  DEFAULT_SYSTEM_MSG = "You are an AI assistant answering only based on the uploaded PDF."
16
  DEFAULT_MAX_TOKENS = 512
17
  DEFAULT_TEMP = 0.3
18
  DEFAULT_TOP_P = 0.95
19
 
20
+ # Get the token from environment variable
21
+ HF_TOKEN = os.getenv('HF_TOKEN')
22
+ client = InferenceClient(
23
+ ChatConfig.MODEL,
24
+ token=HF_TOKEN
25
+ )
26
  embed_model = SentenceTransformer("all-MiniLM-L6-v2", cache_folder="/tmp")
27
  vector_dim = 384 # Embedding size
28
  index = faiss.IndexFlatL2(vector_dim) # FAISS index
29
 
30
  documents = [] # Store extracted text
31
 
32
+ def extract_text_from_pdf(pdf_stream):
33
+ """Extracts text from PDF stream"""
34
+ doc = fitz.open(stream=pdf_stream, filetype="pdf")
35
  text_chunks = [page.get_text("text") for page in doc]
36
+ doc.close()
37
  return text_chunks
38
 
39
  def create_vector_db(text_chunks):
40
  """Embeds text chunks and adds them to FAISS index"""
41
  global documents, index
42
+
43
+ # Reinitialize the FAISS index
44
+ index = faiss.IndexFlatL2(vector_dim)
45
+
46
  documents = text_chunks
47
  embeddings = embed_model.encode(text_chunks)
48
 
 
79
 
80
  context = search_relevant_text(message) # Get relevant content from PDF
81
 
82
+ # Start with the system message in the first user message
83
+ messages = []
84
+ first_msg = f"{system_message}\n\nContext: {context}\nQuestion: {message}"
85
+ messages.append({"role": "user", "content": first_msg})
86
+
87
+ # Add conversation history ensuring alternating pattern (user, assistant, user, assistant...)
88
  for user_msg, bot_msg in history:
89
+ if user_msg.strip(): # Check if user message is not empty
90
  messages.append({"role": "user", "content": user_msg})
91
+ if bot_msg.strip(): # Check if assistant message is not empty
92
  messages.append({"role": "assistant", "content": bot_msg})
93
 
94
+ try:
95
+ response = ""
96
+ for chunk in client.chat_completion(
97
+ messages,
98
+ max_tokens=max_tokens,
99
+ stream=True,
100
+ temperature=temperature,
101
+ top_p=top_p,
102
+ ):
103
+ token = chunk.choices[0].delta.content or ""
104
+ response += token
105
+ yield response
106
+ except Exception as e:
107
+ print(f"Error generating response: {str(e)}")
108
+ yield "I apologize, but I encountered an error while generating the response. Please try again."
109
+
110
  @app.route('/')
111
  def index():
112
  """Serve the HTML page for the user interface"""
113
  return render_template('index.html')
114
 
 
 
 
115
  @app.route('/upload_pdf', methods=['POST'])
116
  def upload_pdf():
117
  """Handle PDF upload"""
118
  if 'pdf' not in request.files:
119
+ return jsonify({"error": "No file part"}), 400
120
 
121
  file = request.files['pdf']
122
  if file.filename == "":
123
+ return jsonify({"error": "No selected file"}), 400
 
 
124
 
125
  try:
126
+ # Read the file directly into memory instead of saving to disk
127
+ pdf_stream = file.read()
128
+
129
+ # Create a BytesIO object to work with the PDF in memory
130
+ from io import BytesIO
131
+ pdf_stream = BytesIO(pdf_stream)
132
+
133
+ # Use fitz to open the PDF from memory
134
+ doc = fitz.open(stream=pdf_stream, filetype="pdf")
135
+ text_chunks = [page.get_text("text") for page in doc]
136
+ doc.close()
137
+
138
+ # Create vector database
139
  create_vector_db(text_chunks)
140
 
141
  return jsonify({"message": "PDF uploaded and indexed successfully!"}), 200
 
148
  message = request.json.get('message')
149
  history = request.json.get('history', [])
150
  response = generate_response(message, history)
151
+ return jsonify({"response": "".join(response)}) # Join all streamed responses
152
 
153
  if __name__ == '__main__':
154
  app.run(debug=True)