Rekham1110 commited on
Commit
372f3ad
·
verified ·
1 Parent(s): 7d214fd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -77
app.py CHANGED
@@ -1,14 +1,9 @@
1
  import gradio as gr
2
  from PIL import Image
3
  import os
4
- import re # Added for regular expression validation
5
  from dotenv import load_dotenv
6
  from simple_salesforce import Salesforce
7
  from datetime import datetime
8
- from fastapi import FastAPI, HTTPException, Security, Depends
9
- from fastapi.security import APIKeyHeader
10
- import base64
11
- import io
12
  import random # For mock predictions
13
 
14
  # Load environment variables
@@ -17,11 +12,9 @@ SF_USERNAME = os.getenv("SF_USERNAME")
17
  SF_PASSWORD = os.getenv("SF_PASSWORD")
18
  SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN")
19
 
20
- API_KEY = os.getenv("API_KEY", "your-api-key-here")
21
-
22
  # Validate Salesforce credentials
23
- if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN ]):
24
- raise ValueError("Missing Salesforce credentials. Set SF_USERNAME, SF_PASSWORD SF_SECURITY_TOKEN in environment variables.")
25
 
26
  # Initialize Salesforce connection
27
  try:
@@ -29,23 +22,12 @@ try:
29
  username=SF_USERNAME,
30
  password=SF_PASSWORD,
31
  security_token=SF_SECURITY_TOKEN,
32
-
33
  domain='login' # Use 'test' for sandbox
34
  )
35
  except Exception as e:
36
  print(f"Salesforce connection failed: {str(e)}")
37
  raise
38
 
39
- # FastAPI app for API endpoint
40
- app = FastAPI()
41
-
42
- # API Key authentication
43
- api_key_header = APIKeyHeader(name="X-API-Key")
44
- async def verify_api_key(api_key: str = Security(api_key_header)):
45
- if api_key != API_KEY:
46
- raise HTTPException(status_code=401, detail="Invalid API Key")
47
- return api_key
48
-
49
  # Mock AI model for milestone detection (since we can't train a real model here)
50
  def mock_ai_model(image):
51
  # Preprocessing: Resize, normalize (simulated)
@@ -71,69 +53,32 @@ def mock_ai_model(image):
71
 
72
  return milestone, completion_percent, confidence_score
73
 
74
- @app.post("/predict-milestone")
75
- async def predict_milestone(payload: dict, api_key: str = Depends(verify_api_key)):
76
- try:
77
- # Validate payload
78
- if "image" not in payload:
79
- raise HTTPException(status_code=400, detail="Image field is required")
80
-
81
- # Decode base64 image
82
- image_data = payload["image"]
83
- if image_data.startswith("data:image"):
84
- image_data = image_data.split(",")[1] # Remove data URI prefix
85
- img_bytes = base64.b64decode(image_data)
86
- img = Image.open(io.BytesIO(img_bytes))
87
-
88
- # Validate image size (max 20MB)
89
- img_bytes_size = len(img_bytes) / (1024 * 1024)
90
- if img_bytes_size > 20:
91
- raise HTTPException(status_code=400, detail="Image size exceeds 20MB")
92
-
93
- # Validate image type
94
- if not img.format.lower() in ["jpeg", "png"]:
95
- raise HTTPException(status_code=400, detail="Only JPG/PNG images are supported")
96
-
97
- # Run mock AI model
98
- milestone, percent_complete, confidence_score = mock_ai_model(img)
99
-
100
- return {
101
- "milestone": milestone,
102
- "percent_complete": percent_complete,
103
- "confidence_score": confidence_score
104
- }
105
-
106
- except Exception as e:
107
- raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")
108
-
109
  # Function for Gradio UI to process the image
110
- def process_image(image, project_name):
111
  try:
112
  # Validate inputs
113
  if image is None:
114
  return "Error: Please upload an image to proceed.", "Pending", "", "", 0
115
- if not project_name:
116
- return "Error: Please enter a project name to proceed.", "Pending", "", "", 0
117
- # Updated validation to allow letters, numbers, spaces, and hyphens
118
- if not re.match(r'^[a-zA-Z0-9\s-]+$', project_name):
119
- return "Error: Project name must be alphanumeric (letters, numbers, spaces, or hyphens).", "Pending", "", "", 0
120
 
121
  # Open and validate image
122
  img = Image.open(image)
123
 
124
  # Validate image size and type
125
  image_size_mb = os.path.getsize(image) / (1024 * 1024)
126
- if image_size_mb_tb > 20:
127
  return "Error: Image size exceeds 20MB.", "Failure", "", "", 0
128
- if not image.lower().endswith(('.jpg', '.jpeg', '.png')):
129
  return "Error: Only JPG/PNG images are supported.", "Failure", "", "", 0
130
 
131
  # Run mock AI model
132
  milestone, percent_complete, confidence_score = mock_ai_model(img)
133
 
134
- # Update Salesforce record
 
 
 
135
  record = {
136
- "Name__c": project_name, # Changed from "Name" to "Name__c"
137
  "Current_Milestone__c": milestone,
138
  "Completion_Percentage__c": percent_complete,
139
  "Last_Updated_On__c": datetime.now().isoformat(),
@@ -142,15 +87,7 @@ def process_image(image, project_name):
142
  }
143
 
144
  try:
145
- # Escape single quotes in project_name to prevent SQL injection
146
- escaped_project_name = project_name.replace("'", "''")
147
- query = f"SELECT Id FROM Construction__c WHERE Name__c = '{escaped_project_name}'"
148
- result = sf.query(query)
149
- if result["totalSize"] > 0:
150
- project_id = result["records"][0]["Id"]
151
- sf.Construction__c.update(project_id, record)
152
- else:
153
- sf.Construction__c.create(record)
154
  except Exception as e:
155
  return f"Error: Failed to update Salesforce - {str(e)}", "Failure", "", "", 0
156
 
@@ -168,7 +105,6 @@ def process_image(image, project_name):
168
  # Gradio interface for testing
169
  with gr.Blocks(css=".gradio-container {background-color: #f0f4f8; font-family: Arial;} .title {color: #2c3e50; font-size: 24px; text-align: center;}") as demo:
170
  gr.Markdown("<h1 class='title'>Construction Milestone Detector</h1>")
171
- project_name = gr.Textbox(label="Project Name", placeholder="Enter project name (e.g., My House or Site-123)")
172
  image_input = gr.Image(type="filepath", label="Upload Construction Site Photo (JPG/PNG, ≤ 20MB)")
173
  submit_button = gr.Button("Process Image")
174
  output_text = gr.Textbox(label="Result")
@@ -179,9 +115,9 @@ with gr.Blocks(css=".gradio-container {background-color: #f0f4f8; font-family: A
179
 
180
  submit_button.click(
181
  fn=process_image,
182
- inputs=[image_input, project_name],
183
  outputs=[output_text, upload_status, milestone, confidence, progress]
184
  )
185
 
186
  # Launch the Gradio app
187
- demo.launch()
 
1
  import gradio as gr
2
  from PIL import Image
3
  import os
 
4
  from dotenv import load_dotenv
5
  from simple_salesforce import Salesforce
6
  from datetime import datetime
 
 
 
 
7
  import random # For mock predictions
8
 
9
  # Load environment variables
 
12
  SF_PASSWORD = os.getenv("SF_PASSWORD")
13
  SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN")
14
 
 
 
15
  # Validate Salesforce credentials
16
+ if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN]):
17
+ raise ValueError("Missing Salesforce credentials. Set SF_USERNAME, SF_PASSWORD, and SF_SECURITY_TOKEN in environment variables.")
18
 
19
  # Initialize Salesforce connection
20
  try:
 
22
  username=SF_USERNAME,
23
  password=SF_PASSWORD,
24
  security_token=SF_SECURITY_TOKEN,
 
25
  domain='login' # Use 'test' for sandbox
26
  )
27
  except Exception as e:
28
  print(f"Salesforce connection failed: {str(e)}")
29
  raise
30
 
 
 
 
 
 
 
 
 
 
 
31
  # Mock AI model for milestone detection (since we can't train a real model here)
32
  def mock_ai_model(image):
33
  # Preprocessing: Resize, normalize (simulated)
 
53
 
54
  return milestone, completion_percent, confidence_score
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  # Function for Gradio UI to process the image
57
+ def process_image(image):
58
  try:
59
  # Validate inputs
60
  if image is None:
61
  return "Error: Please upload an image to proceed.", "Pending", "", "", 0
 
 
 
 
 
62
 
63
  # Open and validate image
64
  img = Image.open(image)
65
 
66
  # Validate image size and type
67
  image_size_mb = os.path.getsize(image) / (1024 * 1024)
68
+ if image_size_mb > 20: # Fixed the typo: image_size_mb_tb to image_size_mb
69
  return "Error: Image size exceeds 20MB.", "Failure", "", "", 0
70
+ if not str(image).lower().endswith(('.jpg', '.jpeg', '.png')):
71
  return "Error: Only JPG/PNG images are supported.", "Failure", "", "", 0
72
 
73
  # Run mock AI model
74
  milestone, percent_complete, confidence_score = mock_ai_model(img)
75
 
76
+ # Generate a unique identifier for the Salesforce record
77
+ unique_id = datetime.now().strftime("%Y%m%d%H%M%S")
78
+
79
+ # Store result in Salesforce
80
  record = {
81
+ "Name__c": unique_id, # Use a timestamp-based unique ID instead of project name
82
  "Current_Milestone__c": milestone,
83
  "Completion_Percentage__c": percent_complete,
84
  "Last_Updated_On__c": datetime.now().isoformat(),
 
87
  }
88
 
89
  try:
90
+ sf.Construction__c.create(record) # Always create a new record
 
 
 
 
 
 
 
 
91
  except Exception as e:
92
  return f"Error: Failed to update Salesforce - {str(e)}", "Failure", "", "", 0
93
 
 
105
  # Gradio interface for testing
106
  with gr.Blocks(css=".gradio-container {background-color: #f0f4f8; font-family: Arial;} .title {color: #2c3e50; font-size: 24px; text-align: center;}") as demo:
107
  gr.Markdown("<h1 class='title'>Construction Milestone Detector</h1>")
 
108
  image_input = gr.Image(type="filepath", label="Upload Construction Site Photo (JPG/PNG, ≤ 20MB)")
109
  submit_button = gr.Button("Process Image")
110
  output_text = gr.Textbox(label="Result")
 
115
 
116
  submit_button.click(
117
  fn=process_image,
118
+ inputs=[image_input],
119
  outputs=[output_text, upload_status, milestone, confidence, progress]
120
  )
121
 
122
  # Launch the Gradio app
123
+ demo.launch(share=True) # Note: share=True may not work in all environments; you may need to run this locally