Rekham1110 commited on
Commit
1101cd0
·
verified ·
1 Parent(s): ae8e4aa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -65
app.py CHANGED
@@ -8,24 +8,17 @@ from PIL import Image
8
  import io
9
  import os
10
  from dotenv import load_dotenv
 
11
 
12
  # Load environment variables
13
  load_dotenv()
14
 
15
  # Configuration
16
  AI_MODEL_ENDPOINT = os.getenv("AI_MODEL_ENDPOINT", "https://your-huggingface-or-lambda-endpoint/predict-milestone")
17
- SALESFORCE_API_URL = os.getenv("SALESFORCE_API_URL", "https://your-salesforce-instance/services/data/v61.0/sobjects/Construction_Project__c")
18
  S3_BUCKET = os.getenv("S3_BUCKET", "your-s3-bucket")
19
  AWS_REGION = os.getenv("AWS_REGION", "us-east-1")
20
  MAX_FILE_SIZE = 20 * 1024 * 1024 # 20MB in bytes
21
  MIN_IMAGE_DIMENSIONS = (800, 600) # Minimum width and height for clarity
22
- SALESFORCE_AUTH = {
23
- "access_token": os.getenv("SALESFORCE_ACCESS_TOKEN"),
24
- "headers": {
25
- "Authorization": f"Bearer {os.getenv('SALESFORCE_ACCESS_TOKEN')}",
26
- "Content-Type": "application/json"
27
- }
28
- }
29
 
30
  # Initialize AWS S3 client
31
  try:
@@ -39,33 +32,58 @@ except Exception as e:
39
  st.error(f"Failed to initialize S3 client: {str(e)}")
40
  st.stop()
41
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  # Streamlit app
43
  st.title("Construction Progress Verifier")
44
- st.write("Upload a construction site photo to track project milestones.")
45
-
46
- # Input for Salesforce Project ID
47
- project_id = st.text_input("Enter Salesforce Project ID (Construction_Project__c Record ID)", "")
48
-
49
- # File uploader
50
- uploaded_file = st.file_uploader("Choose an image (JPG/PNG, <20MB)", type=["jpg", "png"])
51
-
52
- if uploaded_file is not None and project_id:
53
- # Validate file size
54
- if uploaded_file.size > MAX_FILE_SIZE:
55
- st.error("File size exceeds 20MB. Please upload a smaller image.")
56
- else:
57
- # Display progress bar and status
58
- progress_bar = st.progress(0)
59
- status_text = st.empty()
 
 
 
 
 
 
 
 
 
60
 
61
  try:
62
  # Read and validate image
63
- status_text.text("Validating image...")
64
- progress_bar.progress(10)
65
  image = Image.open(uploaded_file)
66
  if image.size < MIN_IMAGE_DIMENSIONS:
67
- st.error("Image resolution too low. Please upload a higher resolution image (min 800x600).")
68
- st.stop()
 
 
 
 
69
 
70
  # Convert image to base64
71
  buffered = io.BytesIO()
@@ -73,14 +91,14 @@ if uploaded_file is not None and project_id:
73
  img_str = base64.b64encode(buffered.getvalue()).decode()
74
 
75
  # Upload image to S3
76
- status_text.text("Uploading image to storage...")
77
- s3_key = f"construction_images/{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
78
  s3_client.put_object(Bucket=S3_BUCKET, Key=s3_key, Body=buffered.getvalue())
79
  s3_url = f"https://{S3_BUCKET}.s3.{AWS_REGION}.amazonaws.com/{s3_key}"
80
- progress_bar.progress(30)
81
 
82
  # Call AI model endpoint
83
- status_text.text("Analyzing image with AI model...")
84
  payload = {"image": img_str}
85
  ai_response = requests.post(
86
  AI_MODEL_ENDPOINT,
@@ -92,45 +110,55 @@ if uploaded_file is not None and project_id:
92
  if ai_response.status_code == 200:
93
  ai_result = ai_response.json()
94
  milestone = ai_result.get("milestone", "Unknown")
95
- completion_percent = ai_result.get("percent_complete", 0)
96
- progress_bar.progress(60)
97
 
98
- # Update Salesforce record
99
- status_text.text("Updating Salesforce record...")
100
- sf_payload = {
101
  "Current_Milestone__c": milestone,
102
- "Completion_Percentage__c": float(completion_percent),
103
  "Last_Updated_Image__c": s3_url,
104
- "Last_Updated_On__c": datetime.utcnow().isoformat(),
105
- "Upload_Status__c": "Success",
106
- "Comments__c": "AI prediction completed successfully"
107
- }
108
-
109
- sf_url = f"{SALESFORCE_API_URL}/{project_id}"
110
- sf_response = requests.patch(sf_url, headers=SALESFORCE_AUTH["headers"], json=sf_payload)
111
-
112
- if sf_response.status_code in [200, 204]:
113
- status_text.text("Success! Salesforce record updated.")
114
- progress_bar.progress(100)
115
- st.success(f"Milestone: {milestone}, Completion: {completion_percent}%")
116
- else:
117
- status_text.text("Failed to update Salesforce.")
118
- progress_bar.progress(0)
119
- st.error(f"Salesforce API error: {sf_response.text}")
120
- st.error("Please try again or contact support.")
121
  else:
122
- status_text.text("AI model failed to process image.")
123
- progress_bar.progress(0)
124
- st.error(f"AI model error: {ai_response.text}")
125
- st.error("Please retake the photo or try again later.")
 
 
126
  except Exception as e:
127
- status_text.text("An error occurred.")
128
- progress_bar.progress(0)
129
- st.error(f"Error: {str(e)}")
130
- st.error("Please retake the photo or contact support.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
- elif uploaded_file is not None and not project_id:
133
- st.warning("Please enter a valid Salesforce Project ID.")
 
 
134
 
135
  # Footer
136
  st.markdown("---")
 
8
  import io
9
  import os
10
  from dotenv import load_dotenv
11
+ from simple_salesforce import Salesforce
12
 
13
  # Load environment variables
14
  load_dotenv()
15
 
16
  # Configuration
17
  AI_MODEL_ENDPOINT = os.getenv("AI_MODEL_ENDPOINT", "https://your-huggingface-or-lambda-endpoint/predict-milestone")
 
18
  S3_BUCKET = os.getenv("S3_BUCKET", "your-s3-bucket")
19
  AWS_REGION = os.getenv("AWS_REGION", "us-east-1")
20
  MAX_FILE_SIZE = 20 * 1024 * 1024 # 20MB in bytes
21
  MIN_IMAGE_DIMENSIONS = (800, 600) # Minimum width and height for clarity
 
 
 
 
 
 
 
22
 
23
  # Initialize AWS S3 client
24
  try:
 
32
  st.error(f"Failed to initialize S3 client: {str(e)}")
33
  st.stop()
34
 
35
+ # Initialize Salesforce client
36
+ try:
37
+ sf = Salesforce(
38
+ username=os.getenv("SF_USERNAME"),
39
+ password=os.getenv("SF_PASSWORD"),
40
+ security_token=os.getenv("SF_SECURITY_TOKEN"),
41
+ domain="login" # Use "test" for sandbox
42
+ )
43
+ except Exception as e:
44
+ st.error(f"Failed to connect to Salesforce: {str(e)}")
45
+ st.stop()
46
+
47
  # Streamlit app
48
  st.title("Construction Progress Verifier")
49
+ st.write("Upload one or more construction site photos to track project milestones.")
50
+
51
+ # Input for Salesforce Construction__c Record ID
52
+ project_id = st.text_input("Enter Salesforce Construction ID (Construction__c Record ID)", "")
53
+
54
+ # File uploader for multiple images
55
+ uploaded_files = st.file_uploader("Choose images (JPG/PNG, <20MB each)", type=["jpg", "png"], accept_multiple_files=True)
56
+
57
+ if uploaded_files and project_id:
58
+ # Initialize results list for output
59
+ results = []
60
+ progress_bar = st.progress(0)
61
+ status_text = st.empty()
62
+ total_images = len(uploaded_files)
63
+ progress_increment = 100 // (total_images * 3) # Divide progress into upload, AI, and Salesforce steps
64
+
65
+ for idx, uploaded_file in enumerate(uploaded_files, 1):
66
+ # Validate file size
67
+ if uploaded_file.size > MAX_FILE_SIZE:
68
+ results.append({
69
+ "filename": uploaded_file.name,
70
+ "status": "Failed",
71
+ "message": "File size exceeds 20MB. Please upload a smaller image."
72
+ })
73
+ continue
74
 
75
  try:
76
  # Read and validate image
77
+ status_text.text(f"Processing image {idx}/{total_images}: Validating {uploaded_file.name}...")
78
+ progress_bar.progress(min((idx - 1) * progress_increment * 3 + progress_increment, 100))
79
  image = Image.open(uploaded_file)
80
  if image.size < MIN_IMAGE_DIMENSIONS:
81
+ results.append({
82
+ "filename": uploaded_file.name,
83
+ "status": "Failed",
84
+ "message": "Image resolution too low. Please upload a higher resolution image (min 800x600)."
85
+ })
86
+ continue
87
 
88
  # Convert image to base64
89
  buffered = io.BytesIO()
 
91
  img_str = base64.b64encode(buffered.getvalue()).decode()
92
 
93
  # Upload image to S3
94
+ status_text.text(f"Processing image {idx}/{total_images}: Uploading {uploaded_file.name} to storage...")
95
+ s3_key = f"construction_images/{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uploaded_file.name}"
96
  s3_client.put_object(Bucket=S3_BUCKET, Key=s3_key, Body=buffered.getvalue())
97
  s3_url = f"https://{S3_BUCKET}.s3.{AWS_REGION}.amazonaws.com/{s3_key}"
98
+ progress_bar.progress(min((idx - 1) * progress_increment * 3 + 2 * progress_increment, 100))
99
 
100
  # Call AI model endpoint
101
+ status_text.text(f"Processing image {idx}/{total_images}: Analyzing {uploaded_file.name} with AI model...")
102
  payload = {"image": img_str}
103
  ai_response = requests.post(
104
  AI_MODEL_ENDPOINT,
 
110
  if ai_response.status_code == 200:
111
  ai_result = ai_response.json()
112
  milestone = ai_result.get("milestone", "Unknown")
 
 
113
 
114
+ # Update Salesforce record using simple-salesforce
115
+ status_text.text(f"Processing image {idx}/{total_images}: Updating Salesforce for {uploaded_file.name}...")
116
+ sf.Construction__c.update(project_id, {
117
  "Current_Milestone__c": milestone,
 
118
  "Last_Updated_Image__c": s3_url,
119
+ "Upload_Status__c": "Success"
120
+ })
121
+
122
+ results.append({
123
+ "filename": uploaded_file.name,
124
+ "status": "Success",
125
+ "milestone": milestone,
126
+ "s3_url": s3_url,
127
+ "message": "Salesforce record updated successfully."
128
+ })
129
+ progress_bar.progress(min(idx * progress_increment * 3, 100))
 
 
 
 
 
 
130
  else:
131
+ results.append({
132
+ "filename": uploaded_file.name,
133
+ "status": "Failed",
134
+ "message": f"AI model error: {ai_response.text}. Please retake the photo or try again."
135
+ })
136
+ progress_bar.progress(min(idx * progress_increment * 3, 100))
137
  except Exception as e:
138
+ results.append({
139
+ "filename": uploaded_file.name,
140
+ "status": "Failed",
141
+ "message": f"Error processing image: {str(e)}. Please retake the photo or contact support."
142
+ })
143
+ progress_bar.progress(min(idx * progress_increment * 3, 100))
144
+
145
+ # Display results
146
+ st.markdown("### Processing Results")
147
+ for result in results:
148
+ if result["status"] == "Success":
149
+ st.success(
150
+ f"**{result['filename']}**: "
151
+ f"Milestone: {result['milestone']}, "
152
+ f"S3 URL: {result['s3_url']}, "
153
+ f"Message: {result['message']}"
154
+ )
155
+ else:
156
+ st.error(f"**{result['filename']}**: {result['message']}")
157
 
158
+ elif uploaded_files and not project_id:
159
+ st.warning("Please enter a valid Salesforce Construction ID.")
160
+ elif project_id and not uploaded_files:
161
+ st.warning("Please upload at least one image.")
162
 
163
  # Footer
164
  st.markdown("---")