barathvasan-dev commited on
Commit
07cff00
·
1 Parent(s): 93c6144

Update: Refactored app.py with improved UI and error handling

Browse files
Files changed (1) hide show
  1. app.py +100 -248
app.py CHANGED
@@ -16,11 +16,7 @@ from database import (
16
  get_vehicles_by_state,
17
  get_hourly_traffic,
18
  get_top_plates,
19
- get_suspicious_vehicles,
20
- HF_TOKEN,
21
- DATABASE_URL,
22
- client,
23
- engine
24
  )
25
 
26
  # =========================================================
@@ -40,18 +36,16 @@ def detect_and_save(image):
40
  if image is None:
41
 
42
  return (
43
- "No image uploaded",
44
- {
45
- "error": "No image uploaded"
46
- }
47
  )
48
 
49
- now = datetime.now()
50
 
51
- date = now.strftime("%Y-%m-%d")
52
- time = now.strftime("%H:%M:%S")
53
 
54
- try:
 
55
 
56
  plate, state, vehicle_type, vehicle_conf, success = detect_plate(image)
57
 
@@ -67,18 +61,17 @@ def detect_and_save(image):
67
  )
68
 
69
  result_text = f"""
70
- Detection Success
71
 
72
- 📅 Date: {date}
73
- Time: {time}
74
 
75
- 🚗 Vehicle Type: {vehicle_type}
76
- 🔢 Plate Number: {plate}
77
- 🌍 State: {state}
78
 
79
- 🎯 Confidence: {round(vehicle_conf, 3)}
80
-
81
- 💾 Saved to Database: {success}
82
  """
83
 
84
  result_json = {
@@ -87,8 +80,8 @@ def detect_and_save(image):
87
  "plate": plate,
88
  "state": state,
89
  "vehicle_type": vehicle_type,
90
- "vehicle_confidence": round(vehicle_conf, 3),
91
- "saved": bool(success and plate)
92
  }
93
 
94
  return result_text, result_json
@@ -96,30 +89,25 @@ def detect_and_save(image):
96
  except Exception as e:
97
 
98
  return (
99
- f"Error: {str(e)}",
100
- {
101
- "error": str(e)
102
- }
103
  )
104
 
105
-
106
  # =========================================================
107
- # QUERY DATABASE
108
  # =========================================================
109
 
110
  def query_database(user_query):
111
 
112
- if not user_query.strip():
113
 
114
- return (
115
- "",
116
- pd.DataFrame(),
117
- {
118
- "error": "Please enter a query"
119
- }
120
- )
121
 
122
- try:
 
 
 
 
123
 
124
  response = run_query(user_query)
125
 
@@ -127,16 +115,11 @@ def query_database(user_query):
127
 
128
  results = response.get("result", [])
129
 
130
- if results and len(results) > 0:
131
-
132
  df = pd.DataFrame(results)
133
-
134
  else:
135
-
136
  df = pd.DataFrame({
137
- "message": [
138
- "No matching records found"
139
- ]
140
  })
141
 
142
  return (
@@ -149,13 +132,12 @@ def query_database(user_query):
149
 
150
  return (
151
  "",
152
- pd.DataFrame(),
153
- {
154
- "error": str(e)
155
- }
156
  )
157
 
158
-
159
  # =========================================================
160
  # CHATBOT
161
  # =========================================================
@@ -172,41 +154,35 @@ def chatbot_query(message, history):
172
 
173
  count = response.get("count", 0)
174
 
175
- if len(results) > 5:
176
- preview = results[:5]
177
- else:
178
- preview = results
179
 
180
  bot_reply = f"""
181
- 🔍 SQL Generated:
182
-
183
  {sql}
184
 
185
- 📊 Results Found: {count}
186
-
187
- 📁 Preview:
188
 
 
189
  {preview}
190
  """
191
 
192
- history.append(
193
- (message, bot_reply)
194
- )
 
 
195
 
196
  return history, ""
197
 
198
  except Exception as e:
199
 
200
- history.append(
201
- (
202
- message,
203
- f"❌ Error: {str(e)}"
204
- )
205
- )
206
 
207
  return history, ""
208
 
209
-
210
  # =========================================================
211
  # ANALYTICS
212
  # =========================================================
@@ -215,50 +191,43 @@ def refresh_analytics():
215
 
216
  try:
217
 
218
- state_data = pd.DataFrame(
219
  get_vehicles_by_state()
220
  )
221
 
222
- hourly_data = pd.DataFrame(
223
  get_hourly_traffic()
224
  )
225
 
226
- top_data = pd.DataFrame(
227
  get_top_plates()
228
  )
229
 
230
- suspicious_data = pd.DataFrame(
231
  get_suspicious_vehicles()
232
  )
233
 
234
  return (
235
- state_data,
236
- hourly_data,
237
- top_data,
238
- suspicious_data
239
  )
240
 
241
  except Exception as e:
242
 
243
- err_df = pd.DataFrame({
244
  "error": [str(e)]
245
  })
246
 
247
- return (
248
- err_df,
249
- err_df,
250
- err_df,
251
- err_df
252
- )
253
-
254
 
255
  # =========================================================
256
- # HEALTH CHECK
257
  # =========================================================
258
 
259
  status, msg = health_check()
260
 
261
-
262
  # =========================================================
263
  # UI
264
  # =========================================================
@@ -268,73 +237,19 @@ with gr.Blocks(
268
  theme=gr.themes.Soft()
269
  ) as demo:
270
 
271
- # =====================================================
272
- # HEADER
273
- # =====================================================
274
-
275
  gr.Markdown("""
276
- # 🚗 Vehicle Intelligence System
277
-
278
- AI-powered Vehicle Detection + NLP-to-SQL Intelligence Platform
279
- """)
280
-
281
- if status:
282
- gr.Success(msg)
283
- else:
284
- gr.Warning(msg)
285
-
286
- # =====================================================
287
- # CONFIGURATION STATUS
288
- # =====================================================
289
-
290
- gr.Markdown("### 🔧 Configuration Status")
291
-
292
- config_status = []
293
-
294
- if HF_TOKEN:
295
- gr.Success("✅ Mistral LLM Configured - NLP features enabled")
296
- else:
297
- gr.Warning("❌ HF_TOKEN missing - NLP/AI features disabled. Add HF_TOKEN to Space Secrets")
298
- config_status.append("HF_TOKEN")
299
-
300
- if DATABASE_URL:
301
- gr.Success("✅ Database Configured - Query features enabled")
302
- else:
303
- gr.Warning("❌ DATABASE_URL missing - Database features disabled. Add DATABASE_URL to Space Secrets")
304
- config_status.append("DATABASE_URL")
305
-
306
- if config_status:
307
- with gr.Group():
308
- gr.Markdown(f"""
309
- ### ⚙️ Setup Instructions
310
-
311
- Your Space is **missing these environment variables**:
312
- - **{', '.join(config_status)}**
313
 
314
- **To fix this:**
315
- 1. Go to Space Settings → Repository secrets
316
- 2. Add the following variables:
317
- - `HF_TOKEN`: Get from https://huggingface.co/settings/tokens
318
- - `DATABASE_URL`: Your PostgreSQL connection string
319
- 3. Restart the Space
320
-
321
- Without these, NLP queries and database operations won't work.
322
  """)
323
 
 
324
 
325
  # =====================================================
326
- # TAB 1 - DETECTION
327
  # =====================================================
328
 
329
- with gr.Tab("🎥 Detection"):
330
-
331
- gr.Markdown("""
332
- Upload a vehicle image for:
333
-
334
- - License Plate Detection
335
- - Vehicle Type Classification
336
- - Database Logging
337
- """)
338
 
339
  with gr.Row():
340
 
@@ -342,12 +257,11 @@ Upload a vehicle image for:
342
 
343
  input_img = gr.Image(
344
  type="numpy",
345
- label="Upload Vehicle Image",
346
- sources=["upload", "webcam"]
347
  )
348
 
349
  detect_btn = gr.Button(
350
- "🔍 Detect Vehicle",
351
  variant="primary"
352
  )
353
 
@@ -355,11 +269,11 @@ Upload a vehicle image for:
355
 
356
  output_text = gr.Textbox(
357
  label="Detection Result",
358
- lines=12
359
  )
360
 
361
  output_json = gr.JSON(
362
- label="Structured Output"
363
  )
364
 
365
  detect_btn.click(
@@ -368,68 +282,35 @@ Upload a vehicle image for:
368
  outputs=[
369
  output_text,
370
  output_json
371
- ],
372
- show_progress=True
373
  )
374
 
375
  # =====================================================
376
- # TAB 2 - NLP QUERY
377
  # =====================================================
378
 
379
- with gr.Tab("🔍 NLP Database Query"):
380
 
381
  gr.Markdown("""
382
- Ask questions using natural language.
383
-
384
- Examples:
385
- - Show TN vehicles
386
- - Track TN63MB3157
387
- - Show traffic in Adyar
388
- - Top repeated plates
389
- - Hourly traffic
390
  """)
391
 
392
  query_input = gr.Textbox(
393
- label="Ask a Question",
394
- placeholder="Example: Show all TN vehicles",
395
- lines=2
396
  )
397
 
398
  search_btn = gr.Button(
399
- "🔍 Search Database",
400
  variant="primary"
401
  )
402
 
403
- gr.Examples(
404
- examples=[
405
- ["Show TN vehicles"],
406
- ["Track TN63MB3157"],
407
- ["Show all vehicles from Adyar"],
408
- ["Top repeated plates"],
409
- ["Hourly traffic"],
410
- ["Show suspicious vehicles"],
411
- ["Show vehicle type distribution"],
412
- ["Show latest detections"],
413
- ["Count vehicles in Guindy"],
414
- ["Show KA state vehicles"],
415
- ["Show buses"],
416
- ["Show traffic on 2026-05-01"]
417
- ],
418
- inputs=query_input
419
  )
420
 
421
- with gr.Row():
422
-
423
- sql_output = gr.Code(
424
- label="Generated SQL",
425
- language="sql"
426
- )
427
-
428
  results_output = gr.Dataframe(
429
- headers=None,
430
- datatype="str",
431
- interactive=False,
432
- wrap=True,
433
  label="Results"
434
  )
435
 
@@ -444,80 +325,67 @@ Examples:
444
  sql_output,
445
  results_output,
446
  json_output
447
- ],
448
- show_progress=True
449
  )
450
 
451
  # =====================================================
452
- # TAB 3 - CHATBOT
453
  # =====================================================
454
 
455
- with gr.Tab("🤖 AI Assistant"):
456
-
457
- gr.Markdown("""
458
- Chat with the Vehicle Intelligence Database
459
- """)
460
 
461
  chatbot = gr.Chatbot(
 
462
  height=500
463
  )
464
 
465
- msg_box = gr.Textbox(
466
  placeholder="Ask something..."
467
  )
468
 
469
- clear_btn = gr.Button("🗑 Clear Chat")
470
 
471
- msg_box.submit(
472
  chatbot_query,
473
- [msg_box, chatbot],
474
- [chatbot, msg_box]
475
  )
476
 
477
- clear_btn.click(
478
- lambda: None,
479
- None,
480
- chatbot,
481
  queue=False
482
  )
483
 
484
  # =====================================================
485
- # TAB 4 - ANALYTICS
486
  # =====================================================
487
 
488
- with gr.Tab("📊 Analytics Dashboard"):
489
-
490
- gr.Markdown("""
491
- Real-time traffic analytics from vehicle intelligence database
492
- """)
493
 
494
  refresh_btn = gr.Button(
495
- "🔄 Refresh Analytics",
496
  variant="primary"
497
  )
498
 
499
  with gr.Row():
500
 
501
  state_table = gr.Dataframe(
502
- label="🚘 Vehicles By State",
503
- interactive=False
504
  )
505
 
506
  hourly_table = gr.Dataframe(
507
- label="🕒 Traffic By Hour",
508
- interactive=False
509
  )
510
 
511
  with gr.Row():
512
 
513
  top_table = gr.Dataframe(
514
- label="🏆 Top Repeated Plates",
515
- interactive=False
516
  )
517
 
518
  suspicious_table = gr.Dataframe(
519
- label="Suspicious Vehicles",
520
- interactive=False
521
  )
522
 
523
  refresh_btn.click(
@@ -540,28 +408,13 @@ Real-time traffic analytics from vehicle intelligence database
540
  ]
541
  )
542
 
543
- # =====================================================
544
- # FOOTER
545
- # =====================================================
546
-
547
- gr.Markdown("""
548
- ---
549
- ### 🚀 Features
550
-
551
- ✅ AI Vehicle Detection
552
- ✅ License Plate Recognition
553
- ✅ NLP-to-SQL Query Engine
554
- ✅ Supabase PostgreSQL Integration
555
- ✅ Analytics Dashboard
556
- ✅ Real-time Vehicle Tracking
557
- ✅ Hugging Face AI Integration
558
- """)
559
-
560
  # =========================================================
561
- # ENABLE QUEUE
562
  # =========================================================
563
 
564
- demo.queue()
 
 
565
 
566
  # =========================================================
567
  # LAUNCH
@@ -571,6 +424,5 @@ if __name__ == "__main__":
571
 
572
  demo.launch(
573
  server_name="0.0.0.0",
574
- server_port=7860,
575
- share=False
576
  )
 
16
  get_vehicles_by_state,
17
  get_hourly_traffic,
18
  get_top_plates,
19
+ get_suspicious_vehicles
 
 
 
 
20
  )
21
 
22
  # =========================================================
 
36
  if image is None:
37
 
38
  return (
39
+ "No image uploaded",
40
+ {"error": "No image uploaded"}
 
 
41
  )
42
 
43
+ try:
44
 
45
+ now = datetime.now()
 
46
 
47
+ date = now.strftime("%Y-%m-%d")
48
+ time = now.strftime("%H:%M:%S")
49
 
50
  plate, state, vehicle_type, vehicle_conf, success = detect_plate(image)
51
 
 
61
  )
62
 
63
  result_text = f"""
64
+ Detection Success
65
 
66
+ Date: {date}
67
+ Time: {time}
68
 
69
+ Vehicle Type: {vehicle_type}
70
+ Plate: {plate}
71
+ State: {state}
72
 
73
+ Confidence: {round(vehicle_conf, 3)}
74
+ Saved: {success}
 
75
  """
76
 
77
  result_json = {
 
80
  "plate": plate,
81
  "state": state,
82
  "vehicle_type": vehicle_type,
83
+ "confidence": round(vehicle_conf, 3),
84
+ "saved": success
85
  }
86
 
87
  return result_text, result_json
 
89
  except Exception as e:
90
 
91
  return (
92
+ f"Error: {str(e)}",
93
+ {"error": str(e)}
 
 
94
  )
95
 
 
96
  # =========================================================
97
+ # NLP QUERY
98
  # =========================================================
99
 
100
  def query_database(user_query):
101
 
102
+ try:
103
 
104
+ if not user_query.strip():
 
 
 
 
 
 
105
 
106
+ return (
107
+ "",
108
+ pd.DataFrame(),
109
+ {"error": "Empty query"}
110
+ )
111
 
112
  response = run_query(user_query)
113
 
 
115
 
116
  results = response.get("result", [])
117
 
118
+ if len(results) > 0:
 
119
  df = pd.DataFrame(results)
 
120
  else:
 
121
  df = pd.DataFrame({
122
+ "message": ["No results found"]
 
 
123
  })
124
 
125
  return (
 
132
 
133
  return (
134
  "",
135
+ pd.DataFrame({
136
+ "error": [str(e)]
137
+ }),
138
+ {"error": str(e)}
139
  )
140
 
 
141
  # =========================================================
142
  # CHATBOT
143
  # =========================================================
 
154
 
155
  count = response.get("count", 0)
156
 
157
+ preview = results[:5]
 
 
 
158
 
159
  bot_reply = f"""
160
+ SQL:
 
161
  {sql}
162
 
163
+ Rows Found: {count}
 
 
164
 
165
+ Preview:
166
  {preview}
167
  """
168
 
169
+ # IMPORTANT FIX
170
+ history = history + [
171
+ {"role": "user", "content": message},
172
+ {"role": "assistant", "content": bot_reply}
173
+ ]
174
 
175
  return history, ""
176
 
177
  except Exception as e:
178
 
179
+ history = history + [
180
+ {"role": "user", "content": message},
181
+ {"role": "assistant", "content": f"Error: {str(e)}"}
182
+ ]
 
 
183
 
184
  return history, ""
185
 
 
186
  # =========================================================
187
  # ANALYTICS
188
  # =========================================================
 
191
 
192
  try:
193
 
194
+ state_df = pd.DataFrame(
195
  get_vehicles_by_state()
196
  )
197
 
198
+ hourly_df = pd.DataFrame(
199
  get_hourly_traffic()
200
  )
201
 
202
+ top_df = pd.DataFrame(
203
  get_top_plates()
204
  )
205
 
206
+ suspicious_df = pd.DataFrame(
207
  get_suspicious_vehicles()
208
  )
209
 
210
  return (
211
+ state_df,
212
+ hourly_df,
213
+ top_df,
214
+ suspicious_df
215
  )
216
 
217
  except Exception as e:
218
 
219
+ err = pd.DataFrame({
220
  "error": [str(e)]
221
  })
222
 
223
+ return err, err, err, err
 
 
 
 
 
 
224
 
225
  # =========================================================
226
+ # HEALTH
227
  # =========================================================
228
 
229
  status, msg = health_check()
230
 
 
231
  # =========================================================
232
  # UI
233
  # =========================================================
 
237
  theme=gr.themes.Soft()
238
  ) as demo:
239
 
 
 
 
 
240
  gr.Markdown("""
241
+ # Vehicle Intelligence System
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
+ AI Powered Vehicle Detection + NLP SQL Engine
 
 
 
 
 
 
 
244
  """)
245
 
246
+ gr.Markdown(f"### {msg}")
247
 
248
  # =====================================================
249
+ # TAB 1
250
  # =====================================================
251
 
252
+ with gr.Tab("Detection"):
 
 
 
 
 
 
 
 
253
 
254
  with gr.Row():
255
 
 
257
 
258
  input_img = gr.Image(
259
  type="numpy",
260
+ label="Upload Image"
 
261
  )
262
 
263
  detect_btn = gr.Button(
264
+ "Detect Vehicle",
265
  variant="primary"
266
  )
267
 
 
269
 
270
  output_text = gr.Textbox(
271
  label="Detection Result",
272
+ lines=10
273
  )
274
 
275
  output_json = gr.JSON(
276
+ label="JSON Output"
277
  )
278
 
279
  detect_btn.click(
 
282
  outputs=[
283
  output_text,
284
  output_json
285
+ ]
 
286
  )
287
 
288
  # =====================================================
289
+ # TAB 2
290
  # =====================================================
291
 
292
+ with gr.Tab("NLP Database Query"):
293
 
294
  gr.Markdown("""
295
+ Ask natural language questions
 
 
 
 
 
 
 
296
  """)
297
 
298
  query_input = gr.Textbox(
299
+ label="Query",
300
+ placeholder="Show TN vehicles"
 
301
  )
302
 
303
  search_btn = gr.Button(
304
+ "Search",
305
  variant="primary"
306
  )
307
 
308
+ sql_output = gr.Code(
309
+ language="sql",
310
+ label="Generated SQL"
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  )
312
 
 
 
 
 
 
 
 
313
  results_output = gr.Dataframe(
 
 
 
 
314
  label="Results"
315
  )
316
 
 
325
  sql_output,
326
  results_output,
327
  json_output
328
+ ]
 
329
  )
330
 
331
  # =====================================================
332
+ # TAB 3
333
  # =====================================================
334
 
335
+ with gr.Tab("AI Assistant"):
 
 
 
 
336
 
337
  chatbot = gr.Chatbot(
338
+ type="messages",
339
  height=500
340
  )
341
 
342
+ msg = gr.Textbox(
343
  placeholder="Ask something..."
344
  )
345
 
346
+ clear = gr.Button("Clear")
347
 
348
+ msg.submit(
349
  chatbot_query,
350
+ [msg, chatbot],
351
+ [chatbot, msg]
352
  )
353
 
354
+ clear.click(
355
+ lambda: [],
356
+ outputs=chatbot,
 
357
  queue=False
358
  )
359
 
360
  # =====================================================
361
+ # TAB 4
362
  # =====================================================
363
 
364
+ with gr.Tab("Analytics"):
 
 
 
 
365
 
366
  refresh_btn = gr.Button(
367
+ "Refresh Analytics",
368
  variant="primary"
369
  )
370
 
371
  with gr.Row():
372
 
373
  state_table = gr.Dataframe(
374
+ label="Vehicles By State"
 
375
  )
376
 
377
  hourly_table = gr.Dataframe(
378
+ label="Traffic By Hour"
 
379
  )
380
 
381
  with gr.Row():
382
 
383
  top_table = gr.Dataframe(
384
+ label="Top Plates"
 
385
  )
386
 
387
  suspicious_table = gr.Dataframe(
388
+ label="Suspicious Vehicles"
 
389
  )
390
 
391
  refresh_btn.click(
 
408
  ]
409
  )
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  # =========================================================
412
+ # QUEUE
413
  # =========================================================
414
 
415
+ demo.queue(
416
+ max_size=20
417
+ )
418
 
419
  # =========================================================
420
  # LAUNCH
 
424
 
425
  demo.launch(
426
  server_name="0.0.0.0",
427
+ server_port=7860
 
428
  )