gopichandra commited on
Commit
bc94eec
·
verified ·
1 Parent(s): 6188ca3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -318
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import os
2
  from paddleocr import PaddleOCR
3
  from PIL import Image
@@ -9,10 +10,12 @@ import pandas as pd
9
  import matplotlib.pyplot as plt
10
  from io import BytesIO
11
  from fuzzywuzzy import process
 
 
12
 
13
  #📌 Attribute mappings: readable names to Salesforce API names
14
  ATTRIBUTE_MAPPING = {
15
- "Product name": "Productname__c",
16
  "Colour": "Colour__c",
17
  "Motortype": "Motortype__c",
18
  "Frequency": "Frequency__c",
@@ -71,12 +74,11 @@ ATTRIBUTE_MAPPING = {
71
  "SRnumber": "SRnumber__c",
72
  "TypeOfEndUse": "TypeOfEndUse__c",
73
  "Model Name": "Model_Name_Number__c",
74
- "coolingmethod": "coolingmethod__c"
75
  }
76
-
77
  # List of product names to match
78
- PRODUCT_NAMES = [
79
- "Centrifugal mono block pump", "SINGLE PHASE MOTOR STARTER", "EasyPact EZC 100",
80
  "Openwell Submersible Pumpset", "Electric Motor", "Self Priming Pump",
81
  "Control panel for single phase submersible pumps", "MOTOR", "Submersible pump set",
82
  "Fusion submersible pump set", "DCT", "Shock proof water proof", "CG COMMERCIAL MOTORS", "Fusion",
@@ -101,7 +103,7 @@ PRODUCT_NAMES = [
101
  "Various Repair and Maintenance Parts", "Earthmax Pump",
102
  "Water Tank, Filters, Water Pump", "Centrifugal Water Pump for Agriculture",
103
  "mono block pumps"
104
- ]
105
 
106
  #📌 Salesforce credentials
107
  SALESFORCE_USERNAME = "venkatramana@sandbox.com"
@@ -219,15 +221,7 @@ def interact_with_salesforce(mode, entry_type, quantity, extracted_text):
219
  except Exception as e:
220
  return f"❌ Error interacting with Salesforce: {str(e)}"
221
 
222
- import pandas as pd
223
- import plotly.express as px
224
- from simple_salesforce import Salesforce
225
-
226
- # Salesforce Credentials (Assumed to be defined elsewhere)
227
- SALESFORCE_USERNAME = "your_username"
228
- SALESFORCE_PASSWORD = "your_password"
229
- SALESFORCE_SECURITY_TOKEN = "your_security_token"
230
-
231
  def pull_data_from_motor_api():
232
  try:
233
  sf = Salesforce(
@@ -236,319 +230,113 @@ def pull_data_from_motor_api():
236
  security_token=SALESFORCE_SECURITY_TOKEN
237
  )
238
  motor_data = sf.apexecute("MotorDataAPI/", method="GET")
239
- if motor_data and isinstance(motor_data, list) and len(motor_data) > 0:
240
- return motor_data # API returns the list of records
241
- else:
242
- print("No data received from MotorDataAPI.")
243
- return []
244
- except Exception as e:
245
- print(f"Error pulling data from MotorDataAPI: {str(e)}")
246
- return []
247
-
248
- def format_salesforce_data():
249
- try:
250
- data = pull_data_from_motor_api()
251
- if isinstance(data, list) and len(data) > 0:
252
- df = pd.DataFrame(data)
253
- df = df.rename(columns={
254
- "Product_Name__c": "Product Name",
255
- "Modal_Name__c": "Model Name",
256
- "Current_Stocks__c": "Current Stocks"
257
- })
258
- # Remove unnecessary columns
259
- df = df[["Product Name", "Model Name", "Current Stocks"]]
260
- return df
261
- else:
262
- print("No valid data available for formatting.")
263
- return None
264
  except Exception as e:
265
- print(f"Error formatting data: {str(e)}")
266
- return None
267
 
268
- def generate_interactive_bar_chart(df):
 
269
  try:
270
- if df is None or df.empty:
271
- print("No data available for visualization.")
272
- return
273
-
274
- fig = px.bar(
275
- df,
276
- x="Product Name",
277
- y="Current Stocks",
278
- hover_data={"Product Name": True, "Current Stocks": True},
279
- text="Current Stocks",
280
- title="Stock Distribution by Product Name"
281
  )
282
- fig.update_traces(textposition='outside')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  fig.update_layout(
284
- xaxis_title="Product Name",
285
- yaxis_title="Current Stocks",
286
- hovermode="x unified"
 
 
 
287
  )
288
- fig.show()
 
289
  except Exception as e:
290
- print(f"Error generating interactive chart: {str(e)}")
291
 
292
- # Fetch and visualize data
293
- data_df = format_salesforce_data()
294
- if data_df is not None and not data_df.empty:
295
- generate_interactive_bar_chart(data_df)
296
- def app():
297
- with gr.Blocks(css="""
298
- /* General Styling */
299
- .gradio-container {
300
- background: #0b0f29; /* Deep Dark Blue */
301
- font-family: 'Poppins', sans-serif;
302
- color: white;
303
- padding: 10px;
304
- }
305
-
306
- h1, h2, h3 {
307
- text-align: center;
308
- color: white;
309
- font-weight: bold;
310
- text-shadow: 0px 0px 10px rgba(255,255,255,0.8);
311
- }
312
-
313
- /* Cards & Elements */
314
- .card {
315
- background: rgba(255, 255, 255, 0.1);
316
- border-radius: 15px;
317
- padding: 20px;
318
- width: 100%;
319
- max-width: 900px; /* Prevents extra-wide tables */
320
- margin: auto; /* Centers the table */
321
- box-shadow: 0px 0px 25px rgba(0, 255, 255, 0.6);
322
- transition: 0.3s;
323
- }
324
-
325
- .card:hover {
326
- box-shadow: 0px 0px 30px rgba(0, 255, 255, 0.9);
327
- }
328
-
329
- /* Buttons */
330
- .gradio-button {
331
- background: linear-gradient(to right, #ff416c, #ff4b2b);
332
- color: white !important;
333
- border-radius: 10px !important;
334
- font-weight: bold;
335
- padding: 12px;
336
- transition: all 0.3s ease-in-out;
337
- box-shadow: 0px 0px 20px rgba(255, 0, 255, 0.6);
338
- }
339
-
340
- .gradio-button:hover {
341
- background: linear-gradient(to right, #ff4b2b, #ff416c);
342
- box-shadow: 0px 0px 30px rgba(255, 0, 255, 0.9);
343
- }
344
-
345
- /* Tabs */
346
- .gradio-tab {
347
- font-size: 16px;
348
- color: white;
349
- font-weight: bold;
350
- text-shadow: 0px 0px 10px rgba(255, 255, 255, 0.6);
351
- }
352
-
353
- /* Scrollable Table */
354
- .table-container {
355
- width: 100%;
356
- max-width: 900px;
357
- max-height: 400px; /* Controls table height */
358
- overflow-y: auto; /* Enables vertical scrolling */
359
- overflow-x: auto; /* Enables horizontal scrolling if needed */
360
- display: flex;
361
- justify-content: center;
362
- margin: auto;
363
- }
364
-
365
- table {
366
- width: 100%;
367
- border-collapse: collapse;
368
- background: rgba(255, 255, 255, 0.1);
369
- color: white;
370
- min-width: 600px;
371
- }
372
-
373
- th, td {
374
- padding: 12px;
375
- text-align: left;
376
- border-bottom: 1px solid rgba(255, 255, 255, 0.2);
377
- font-size: 14px;
378
- }
379
-
380
- th {
381
- background: rgba(0, 255, 255, 0.2);
382
- }
383
-
384
- /* Mobile View */
385
- @media (max-width: 768px) {
386
- .gradio-container {
387
- padding: 10px;
388
- }
389
-
390
- .card {
391
- width: 100%;
392
- max-width: 100%;
393
- padding: 10px;
394
- }
395
-
396
- .table-container {
397
- max-height: 350px; /* Adjusts for mobile */
398
- overflow-y: scroll; /* Ensures vertical scrolling */
399
- }
400
-
401
- table {
402
- width: 100%;
403
- min-width: 100%;
404
- }
405
-
406
- th, td {
407
- font-size: 12px;
408
- padding: 8px;
409
- }
410
- }
411
-
412
- """) as interface:
413
-
414
- gr.Markdown("<h1>🏢 VENKATARAMANA MOTORS</h1>")
415
-
416
- with gr.Tab("📥 Stock Entry & Processing"):
417
- with gr.Row():
418
- with gr.Column():
419
- gr.Markdown("<h3>📌 Upload & Process</h3>")
420
- image_input = gr.Image(type="numpy", label="📄 Upload Image", elem_classes="card")
421
- mode_dropdown = gr.Dropdown(label="📌 Mode", choices=["Entry", "Exit"], value="Entry", elem_classes="card")
422
- entry_type_radio = gr.Radio(label="📦 Entry Type", choices=["Sales", "Non-Sales"], value="Sales", elem_classes="card")
423
- quantity_input = gr.Number(label="🔢 Quantity", value=1, interactive=True, elem_classes="card")
424
-
425
- with gr.Column():
426
- gr.Markdown("<h3>📊 Processed Data</h3>")
427
- image_view = gr.Text(label="📜 Image Data Viewer", interactive=False, elem_classes="card")
428
- result_output = gr.Text(label="📝 Processed Result", interactive=False, elem_classes="card")
429
- submit_button = gr.Button("🔍 Process Image", elem_id="process-btn", elem_classes="gradio-button")
430
-
431
- with gr.Tab("📊 Salesforce Data Overview"):
432
- gr.Markdown("<h3>📑 Stock Table</h3>")
433
- with gr.Row(elem_classes="table-container"):
434
- salesforce_table = gr.HTML(label="📦 Salesforce Data Table", elem_classes="card")
435
-
436
- gr.Markdown("<h3>📈 Inventory Analytics</h3>")
437
- with gr.Row():
438
- salesforce_graph = gr.Image(type="pil", label="📉 Stock Distribution Bar Graph", elem_classes="card")
439
-
440
- generate_button = gr.Button("⚡ Generate Data", elem_classes="gradio-button")
441
-
442
- # Clicking "Generate Data" fetches table & graph
443
- generate_button.click(fn=generate_salesforce_data, inputs=[], outputs=[salesforce_table, salesforce_graph])
444
-
445
- submit_button.click(fn=process_image, inputs=[image_input, mode_dropdown, entry_type_radio, quantity_input], outputs=[image_view, result_output])
446
-
447
- return interface
448
-
449
- interface = app()
450
- interface.launch()
451
- css = """
452
- body {
453
- background: linear-gradient(135deg, #282c34, #4b79a1);
454
- font-family: 'Poppins', sans-serif;
455
- }
456
-
457
- .gradio-container {
458
- border-radius: 20px;
459
- padding: 30px;
460
- background: rgba(255, 255, 255, 0.2);
461
- backdrop-filter: blur(10px);
462
- box-shadow: 0px 8px 30px rgba(0, 123, 255, 0.4);
463
- border: 2px solid rgba(255, 255, 255, 0.4);
464
- }
465
-
466
- .gradio-title {
467
- font-size: 48px;
468
- font-weight: bold;
469
- text-align: center;
470
- background: linear-gradient(90deg, #ff7eb3, #ff758c);
471
- -webkit-background-clip: text;
472
- -webkit-text-fill-color: transparent;
473
- text-shadow: 5px 5px 20px rgba(255, 105, 180, 0.6);
474
- margin-bottom: 20px;
475
- animation: glow 2s infinite alternate;
476
- }
477
-
478
- @keyframes glow {
479
- from {
480
- text-shadow: 5px 5px 30px rgba(255, 87, 134, 0.6);
481
- }
482
- to {
483
- text-shadow: 6px 6px 40px rgba(255, 54, 90, 1);
484
- }
485
- }
486
-
487
- .gradio-box {
488
- border-radius: 15px;
489
- padding: 25px;
490
- background: linear-gradient(135deg, #6a11cb, #2575fc);
491
- box-shadow: 0px 6px 25px rgba(30, 144, 255, 0.6);
492
- border: 2px solid #6a5acd;
493
- color: white;
494
- font-size: 18px;
495
- }
496
-
497
- .gradio-button {
498
- border-radius: 12px;
499
- padding: 18px 36px;
500
- font-size: 20px;
501
- font-weight: bold;
502
- color: #fff;
503
- background: linear-gradient(135deg, #1e90ff, #00bfff);
504
- box-shadow: 0px 6px 25px rgba(0, 191, 255, 0.6);
505
- transition: all 0.3s ease-in-out;
506
- }
507
-
508
- .gradio-button:hover {
509
- background: linear-gradient(135deg, #00bfff, #1e90ff);
510
- box-shadow: 0px 10px 35px rgba(0, 191, 255, 0.9);
511
- transform: scale(1.1);
512
- }
513
-
514
- .gradio-input {
515
- border-radius: 10px;
516
- padding: 16px;
517
- font-size: 18px;
518
- background: rgba(255, 255, 255, 0.3);
519
- border: 2px solid rgba(0, 123, 255, 0.5);
520
- color: #fff;
521
- transition: 0.3s;
522
- }
523
-
524
- .gradio-input:focus {
525
- border: 2px solid #1e90ff;
526
- outline: none;
527
- box-shadow: 0px 5px 20px rgba(30, 144, 255, 0.6);
528
- }
529
-
530
- .gradio-output {
531
- background: linear-gradient(135deg, #f39c12, #e74c3c);
532
- padding: 22px;
533
- border-radius: 15px;
534
- color: white;
535
- font-size: 20px;
536
- text-align: center;
537
- border: 2px solid #f39c12;
538
- }
539
-
540
- .gradio-file {
541
- background: linear-gradient(135deg, #8e44ad, #3498db);
542
- color: white;
543
- padding: 16px;
544
- border-radius: 15px;
545
- text-align: center;
546
- font-size: 18px;
547
- }
548
- """
549
 
 
 
 
 
550
 
 
 
551
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
 
553
  if __name__ == "__main__":
554
- app().launch(share=True)
 
 
1
+
2
  import os
3
  from paddleocr import PaddleOCR
4
  from PIL import Image
 
10
  import matplotlib.pyplot as plt
11
  from io import BytesIO
12
  from fuzzywuzzy import process
13
+ import plotly.graph_objects as go
14
+ import kaleido # Ensure kaleido is imported
15
 
16
  #📌 Attribute mappings: readable names to Salesforce API names
17
  ATTRIBUTE_MAPPING = {
18
+ "Product name": "Productname__c",
19
  "Colour": "Colour__c",
20
  "Motortype": "Motortype__c",
21
  "Frequency": "Frequency__c",
 
74
  "SRnumber": "SRnumber__c",
75
  "TypeOfEndUse": "TypeOfEndUse__c",
76
  "Model Name": "Model_Name_Number__c",
77
+ "coolingmethod": "coolingmethod__c"
78
  }
79
+
80
  # List of product names to match
81
+ PRODUCT_NAMES = ["Centrifugal mono block pump", "SINGLE PHASE MOTOR STARTER", "EasyPact EZC 100",
 
82
  "Openwell Submersible Pumpset", "Electric Motor", "Self Priming Pump",
83
  "Control panel for single phase submersible pumps", "MOTOR", "Submersible pump set",
84
  "Fusion submersible pump set", "DCT", "Shock proof water proof", "CG COMMERCIAL MOTORS", "Fusion",
 
103
  "Various Repair and Maintenance Parts", "Earthmax Pump",
104
  "Water Tank, Filters, Water Pump", "Centrifugal Water Pump for Agriculture",
105
  "mono block pumps"
106
+ ]
107
 
108
  #📌 Salesforce credentials
109
  SALESFORCE_USERNAME = "venkatramana@sandbox.com"
 
221
  except Exception as e:
222
  return f"❌ Error interacting with Salesforce: {str(e)}"
223
 
224
+ # Function to pull data from Salesforce MotorDataAPI
 
 
 
 
 
 
 
 
225
  def pull_data_from_motor_api():
226
  try:
227
  sf = Salesforce(
 
230
  security_token=SALESFORCE_SECURITY_TOKEN
231
  )
232
  motor_data = sf.apexecute("MotorDataAPI/", method="GET")
233
+ return motor_data # API returns the list of records
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  except Exception as e:
235
+ return f"Error pulling data from MotorDataAPI: {str(e)}"
 
236
 
237
+ # Function to pull structured data from Salesforce and display as a table
238
+ def pull_data_from_salesforce():
239
  try:
240
+ sf = Salesforce(
241
+ username=SALESFORCE_USERNAME,
242
+ password=SALESFORCE_PASSWORD,
243
+ security_token=SALESFORCE_SECURITY_TOKEN
 
 
 
 
 
 
 
244
  )
245
+
246
+ query = "SELECT Product_Name__c, Modal_Name__c, Current_Stocks__c FROM Inventory_Management__c LIMIT 100"
247
+ response = sf.query_all(query)
248
+
249
+ records = response.get("records", [])
250
+ if not records:
251
+ return "No data found in Salesforce.", None, None, None
252
+
253
+ df = pd.DataFrame(records)
254
+ df = df.drop(columns=['attributes'], errors='ignore')
255
+
256
+ # Rename columns for better readability
257
+ df.rename(columns={
258
+ "Product_Name__c": "Product Name",
259
+ "Modal_Name__c": "Model Name",
260
+ "Current_Stocks__c": "Current Stocks"
261
+ }, inplace=True)
262
+
263
+ excel_path = "salesforce_data.xlsx"
264
+ df.to_excel(excel_path, index=False)
265
+
266
+ # Generate interactive bar graph using Plotly with Tooltip, Hover Effect, and Zooming
267
+ fig = go.Figure()
268
+ fig.add_trace(go.Bar(
269
+ x=df['Product Name'],
270
+ y=df['Current Stocks'],
271
+ marker=dict(color='blue'),
272
+ hoverinfo='x+y',
273
+ hovertemplate='<b>Product Name:</b> %{x}<br><b>Current Stocks:</b> %{y}<extra></extra>',
274
+ text=df['Current Stocks'],
275
+ textposition='outside'
276
+ ))
277
+
278
  fig.update_layout(
279
+ title="Current Stocks of Products",
280
+ xaxis=dict(title="Product Name", tickangle=-45),
281
+ yaxis=dict(title="Stock Quantity"),
282
+ hovermode='x',
283
+ dragmode='zoom',
284
+ showlegend=False
285
  )
286
+
287
+ return "Data successfully retrieved.", df, excel_path, fig
288
  except Exception as e:
289
+ return f"Error fetching data: {str(e)}", None, None, None
290
 
291
+ # Unified function to handle image processing and Salesforce interaction
292
+ def process_image(image, mode, entry_type, quantity):
293
+ extracted_text = extract_text(image)
294
+ if not extracted_text:
295
+ return "No text detected in the image.", None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
+ product_name = match_product_name(extracted_text)
298
+ attributes = extract_attributes(extracted_text)
299
+ if product_name:
300
+ attributes["Product name"] = product_name
301
 
302
+ # Interact with Salesforce
303
+ message = interact_with_salesforce(mode, entry_type, quantity, extracted_text)
304
 
305
+ numbered_output = "\n".join([f"{key}: {value}" for key, value in attributes.items()])
306
+ return f"Extracted Text:\n{extracted_text}\n\nAttributes and Values:\n{numbered_output}", message
307
+
308
+ # Gradio Interface
309
+ def app():
310
+ return gr.TabbedInterface([
311
+ gr.Interface(
312
+ fn=process_image,
313
+ inputs=[
314
+ gr.Image(type="numpy", label="Upload Image"),
315
+ gr.Dropdown(label="Mode", choices=["Entry", "Exit"], value="Entry"),
316
+ gr.Radio(label="Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
317
+ gr.Number(label="Quantity", value=1, interactive=False),
318
+ ],
319
+ outputs=[
320
+ gr.Text(label="Extracted Text"),
321
+ gr.Text(label="Result")
322
+ ],
323
+ title="Image Text Extraction",
324
+ description="Upload an image and extract text using OCR."
325
+ ),
326
+ gr.Interface(
327
+ fn=pull_data_from_salesforce,
328
+ inputs=[],
329
+ outputs=[
330
+ gr.Text(label="Status"),
331
+ gr.Dataframe(label="Salesforce Data Table"),
332
+ gr.File(label="Download Salesforce Data"),
333
+ gr.Plot(label="Stock Distribution Bar Graph")
334
+ ],
335
+ title="Salesforce Data Export",
336
+ description="View, visualize (zoom-in/out, hover details), and download Salesforce data (Product Name, Model Name, Current Stocks)."
337
+ )
338
+ ], ["OCR Processing", "Salesforce Data Export"])
339
 
340
  if __name__ == "__main__":
341
+ app().launch(share=True)
342
+