WebashalarForML commited on
Commit
e38f376
·
verified ·
1 Parent(s): 92efc65

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -19
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from flask import Flask, render_template, request, redirect, url_for, send_from_directory
2
  from flask_socketio import SocketIO
3
  import threading
4
  import os
@@ -62,6 +62,15 @@ def create_agent_app(db_path: str):
62
  # -------------------------------------------------------------------------
63
  @tool
64
  def db_query_tool(query: str) -> str:
 
 
 
 
 
 
 
 
 
65
  result = db_instance.run_no_throw(query)
66
  return result if result else "Error: Query failed. Please rewrite your query and try again."
67
 
@@ -116,7 +125,7 @@ def create_agent_app(db_path: str):
116
  "If you get an empty result set, you should try to rewrite the query to get a non-empty result set.\n"
117
  "NEVER make stuff up if you don't have enough information to answer the query... just say you don't have enough information.\n\n"
118
  "If you have enough information to answer the input question, simply invoke the appropriate tool to submit the final answer to the user.\n"
119
- "DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database. Do not return any sql query except answer."
120
  )
121
  query_gen_prompt = ChatPromptTemplate.from_messages([
122
  ("system", query_gen_system),
@@ -124,25 +133,32 @@ def create_agent_app(db_path: str):
124
  ])
125
  query_gen = query_gen_prompt | llm.bind_tools([SubmitFinalAnswer])
126
 
127
- # Update database URI and file path
 
 
128
  abs_db_path_local = os.path.abspath(db_path)
129
  global DATABASE_URI
130
  DATABASE_URI = abs_db_path_local
131
  db_uri = f"sqlite:///{abs_db_path_local}"
132
  print("db_uri", db_uri)
133
- flash(f"db_uri:{db_uri}", "warning")
134
- # Create SQLDatabase connection using langchain utility.
 
135
  from langchain_community.utilities import SQLDatabase
136
  db_instance = SQLDatabase.from_uri(db_uri)
137
  print("db_instance----->", db_instance)
138
- flash(f"db_instance:{db_instance}", "warning")
139
 
 
140
  # Create SQL toolkit.
 
141
  from langchain_community.agent_toolkits import SQLDatabaseToolkit
142
  toolkit_instance = SQLDatabaseToolkit(db=db_instance, llm=llm)
143
  tools_instance = toolkit_instance.get_tools()
144
 
 
145
  # Define workflow nodes and fallback functions.
 
146
  def first_tool_call(state: State) -> dict[str, list[AIMessage]]:
147
  return {"messages": [AIMessage(content="", tool_calls=[{"name": "sql_db_list_tables", "args": {}, "id": "tool_abcd123"}])]}
148
 
@@ -181,7 +197,9 @@ def create_agent_app(db_path: str):
181
  def model_check_query(state: State) -> dict[str, list[AIMessage]]:
182
  return {"messages": [query_check.invoke({"messages": [state["messages"][-1]]})]}
183
 
184
- # Get table listing and schema tools.
 
 
185
  list_tables_tool = next((tool for tool in tools_instance if tool.name == "sql_db_list_tables"), None)
186
  get_schema_tool = next((tool for tool in tools_instance if tool.name == "sql_db_schema"), None)
187
 
@@ -207,11 +225,11 @@ def create_agent_app(db_path: str):
207
  # Return compiled workflow
208
  return workflow.compile()
209
 
 
210
  # =============================================================================
211
  # create_app: The application factory.
212
  # =============================================================================
213
  def create_app():
214
- # Configure static folder for uploads.
215
  flask_app = Flask(__name__, static_url_path='/uploads', static_folder='uploads')
216
  socketio = SocketIO(flask_app, cors_allowed_origins="*")
217
 
@@ -220,7 +238,9 @@ def create_app():
220
  os.makedirs(UPLOAD_FOLDER)
221
  flask_app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
222
 
 
223
  # Serve uploaded files via a custom route.
 
224
  @flask_app.route("/files/<path:filename>")
225
  def uploaded_file(filename):
226
  return send_from_directory(flask_app.config['UPLOAD_FOLDER'], filename)
@@ -229,26 +249,26 @@ def create_app():
229
  # Helper: run_agent runs the agent with the given prompt.
230
  # -------------------------------------------------------------------------
231
  def run_agent(prompt, socketio):
232
- global agent_app, abs_file_path
233
  if not abs_file_path:
234
  socketio.emit("log", {"message": "[ERROR]: No DB file uploaded."})
235
  socketio.emit("final", {"message": "No database available. Please upload one and try again."})
236
  return
237
-
238
  try:
239
- # Lazy agent init
240
  if agent_app is None:
241
  print("[INFO]: Initializing agent for the first time...")
242
  agent_app = create_agent_app(abs_file_path)
243
  socketio.emit("log", {"message": "[INFO]: Agent initialized."})
244
-
245
  query = {"messages": [("user", prompt)]}
246
  result = agent_app.invoke(query)
247
  try:
248
  result = result["messages"][-1].tool_calls[0]["args"]["final_answer"]
249
  except Exception:
250
  result = "Query failed or no valid answer found."
251
-
252
  print("final_answer------>", result)
253
  socketio.emit("final", {"message": result})
254
  except Exception as e:
@@ -256,16 +276,15 @@ def create_app():
256
  socketio.emit("log", {"message": f"[ERROR]: {str(e)}"})
257
  socketio.emit("final", {"message": "Generation failed."})
258
 
259
-
260
  # -------------------------------------------------------------------------
261
- # Route: index page
262
  # -------------------------------------------------------------------------
263
  @flask_app.route("/")
264
  def index():
265
  return render_template("index.html")
266
 
267
  # -------------------------------------------------------------------------
268
- # Route: generate (POST) – receives a prompt, runs the agent.
269
  # -------------------------------------------------------------------------
270
  @flask_app.route("/generate", methods=["POST"])
271
  def generate():
@@ -280,7 +299,6 @@ def create_app():
280
  return "OK", 200
281
  except Exception as e:
282
  print(f"[ERROR]: {str(e)}")
283
- flash(f"[ERROR]: {str(e)}", "error")
284
  socketio.emit("log", {"message": f"[ERROR]: {str(e)}"})
285
  return "ERROR", 500
286
 
@@ -289,17 +307,19 @@ def create_app():
289
  # -------------------------------------------------------------------------
290
  @flask_app.route("/upload", methods=["GET", "POST"])
291
  def upload():
292
- global abs_file_path, db_path
293
  try:
294
  if request.method == "POST":
295
  file = request.files.get("file")
296
  if not file:
 
297
  return "No file uploaded", 400
298
  filename = secure_filename(file.filename)
299
  if filename.endswith('.db'):
300
  db_path = os.path.join(flask_app.config['UPLOAD_FOLDER'], "uploaded.db")
 
301
  file.save(db_path)
302
- abs_file_path = os.path.abspath(db_path) # Save it here, don't create agent
303
  print(f"[INFO]: File '{filename}' uploaded. Agent will be initialized on first query.")
304
  socketio.emit("log", {"message": f"[INFO]: Database file '{filename}' uploaded."})
305
  return redirect(url_for("index"))
 
1
+ from flask import Flask, render_template, request, redirect, url_for, send_from_directory, flash
2
  from flask_socketio import SocketIO
3
  import threading
4
  import os
 
62
  # -------------------------------------------------------------------------
63
  @tool
64
  def db_query_tool(query: str) -> str:
65
+ """
66
+ Executes a SQL query on the connected SQLite database.
67
+
68
+ Parameters:
69
+ query (str): A SQL query string to be executed.
70
+
71
+ Returns:
72
+ str: The result from the database if successful, or an error message if not.
73
+ """
74
  result = db_instance.run_no_throw(query)
75
  return result if result else "Error: Query failed. Please rewrite your query and try again."
76
 
 
125
  "If you get an empty result set, you should try to rewrite the query to get a non-empty result set.\n"
126
  "NEVER make stuff up if you don't have enough information to answer the query... just say you don't have enough information.\n\n"
127
  "If you have enough information to answer the input question, simply invoke the appropriate tool to submit the final answer to the user.\n"
128
+ "DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database. Do not return any SQL query except answer."
129
  )
130
  query_gen_prompt = ChatPromptTemplate.from_messages([
131
  ("system", query_gen_system),
 
133
  ])
134
  query_gen = query_gen_prompt | llm.bind_tools([SubmitFinalAnswer])
135
 
136
+ # -------------------------------------------------------------------------
137
+ # Update database URI and file path, create SQLDatabase connection.
138
+ # -------------------------------------------------------------------------
139
  abs_db_path_local = os.path.abspath(db_path)
140
  global DATABASE_URI
141
  DATABASE_URI = abs_db_path_local
142
  db_uri = f"sqlite:///{abs_db_path_local}"
143
  print("db_uri", db_uri)
144
+ # Uncomment if flash is needed; ensure you have flask.flash imported if so.
145
+ # flash(f"db_uri:{db_uri}", "warning")
146
+
147
  from langchain_community.utilities import SQLDatabase
148
  db_instance = SQLDatabase.from_uri(db_uri)
149
  print("db_instance----->", db_instance)
150
+ # flash(f"db_instance:{db_instance}", "warning")
151
 
152
+ # -------------------------------------------------------------------------
153
  # Create SQL toolkit.
154
+ # -------------------------------------------------------------------------
155
  from langchain_community.agent_toolkits import SQLDatabaseToolkit
156
  toolkit_instance = SQLDatabaseToolkit(db=db_instance, llm=llm)
157
  tools_instance = toolkit_instance.get_tools()
158
 
159
+ # -------------------------------------------------------------------------
160
  # Define workflow nodes and fallback functions.
161
+ # -------------------------------------------------------------------------
162
  def first_tool_call(state: State) -> dict[str, list[AIMessage]]:
163
  return {"messages": [AIMessage(content="", tool_calls=[{"name": "sql_db_list_tables", "args": {}, "id": "tool_abcd123"}])]}
164
 
 
197
  def model_check_query(state: State) -> dict[str, list[AIMessage]]:
198
  return {"messages": [query_check.invoke({"messages": [state["messages"][-1]]})]}
199
 
200
+ # -------------------------------------------------------------------------
201
+ # Get tools for listing tables and fetching schema.
202
+ # -------------------------------------------------------------------------
203
  list_tables_tool = next((tool for tool in tools_instance if tool.name == "sql_db_list_tables"), None)
204
  get_schema_tool = next((tool for tool in tools_instance if tool.name == "sql_db_schema"), None)
205
 
 
225
  # Return compiled workflow
226
  return workflow.compile()
227
 
228
+
229
  # =============================================================================
230
  # create_app: The application factory.
231
  # =============================================================================
232
  def create_app():
 
233
  flask_app = Flask(__name__, static_url_path='/uploads', static_folder='uploads')
234
  socketio = SocketIO(flask_app, cors_allowed_origins="*")
235
 
 
238
  os.makedirs(UPLOAD_FOLDER)
239
  flask_app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
240
 
241
+ # -------------------------------------------------------------------------
242
  # Serve uploaded files via a custom route.
243
+ # -------------------------------------------------------------------------
244
  @flask_app.route("/files/<path:filename>")
245
  def uploaded_file(filename):
246
  return send_from_directory(flask_app.config['UPLOAD_FOLDER'], filename)
 
249
  # Helper: run_agent runs the agent with the given prompt.
250
  # -------------------------------------------------------------------------
251
  def run_agent(prompt, socketio):
252
+ global agent_app, abs_file_path, db_path
253
  if not abs_file_path:
254
  socketio.emit("log", {"message": "[ERROR]: No DB file uploaded."})
255
  socketio.emit("final", {"message": "No database available. Please upload one and try again."})
256
  return
257
+
258
  try:
259
+ # Lazy agent initialization: use the previously uploaded DB.
260
  if agent_app is None:
261
  print("[INFO]: Initializing agent for the first time...")
262
  agent_app = create_agent_app(abs_file_path)
263
  socketio.emit("log", {"message": "[INFO]: Agent initialized."})
264
+
265
  query = {"messages": [("user", prompt)]}
266
  result = agent_app.invoke(query)
267
  try:
268
  result = result["messages"][-1].tool_calls[0]["args"]["final_answer"]
269
  except Exception:
270
  result = "Query failed or no valid answer found."
271
+
272
  print("final_answer------>", result)
273
  socketio.emit("final", {"message": result})
274
  except Exception as e:
 
276
  socketio.emit("log", {"message": f"[ERROR]: {str(e)}"})
277
  socketio.emit("final", {"message": "Generation failed."})
278
 
 
279
  # -------------------------------------------------------------------------
280
+ # Route: index page.
281
  # -------------------------------------------------------------------------
282
  @flask_app.route("/")
283
  def index():
284
  return render_template("index.html")
285
 
286
  # -------------------------------------------------------------------------
287
+ # Route: generate (POST) – receives a prompt and runs the agent.
288
  # -------------------------------------------------------------------------
289
  @flask_app.route("/generate", methods=["POST"])
290
  def generate():
 
299
  return "OK", 200
300
  except Exception as e:
301
  print(f"[ERROR]: {str(e)}")
 
302
  socketio.emit("log", {"message": f"[ERROR]: {str(e)}"})
303
  return "ERROR", 500
304
 
 
307
  # -------------------------------------------------------------------------
308
  @flask_app.route("/upload", methods=["GET", "POST"])
309
  def upload():
310
+ global abs_file_path, agent_app, db_path
311
  try:
312
  if request.method == "POST":
313
  file = request.files.get("file")
314
  if not file:
315
+ print("No file uploaded")
316
  return "No file uploaded", 400
317
  filename = secure_filename(file.filename)
318
  if filename.endswith('.db'):
319
  db_path = os.path.join(flask_app.config['UPLOAD_FOLDER'], "uploaded.db")
320
+ print("Saving file to:", db_path)
321
  file.save(db_path)
322
+ abs_file_path = os.path.abspath(db_path) # Save it here; agent init will occur on first query.
323
  print(f"[INFO]: File '{filename}' uploaded. Agent will be initialized on first query.")
324
  socketio.emit("log", {"message": f"[INFO]: Database file '{filename}' uploaded."})
325
  return redirect(url_for("index"))