Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
|
|
|
|
|
|
|
|
|
|
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(
|
28 |
-
"""Extracts text from PDF"""
|
29 |
-
doc = fitz.open(
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
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
|
107 |
|
108 |
file = request.files['pdf']
|
109 |
if file.filename == "":
|
110 |
-
return jsonify({"error": "No selected file"}), 400
|
111 |
-
|
112 |
-
pdf_path = os.path.join(UPLOAD_FOLDER, file.filename)
|
113 |
|
114 |
try:
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|