Spaces:
Runtime error
Runtime error
File size: 7,296 Bytes
c2fa27a 58f1841 a5fe846 ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 a5fe846 58f1841 f3b82b8 a5fe846 ee60524 a5fe846 ee60524 a5fe846 ee60524 a5fe846 ee60524 a5fe846 ee60524 a5fe846 ee60524 58f1841 c2fa27a 58f1841 c2fa27a ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 ee60524 58f1841 ee60524 c2fa27a ee60524 58f1841 c2fa27a ee60524 c2fa27a ee60524 c2fa27a ee60524 58f1841 ee60524 c2fa27a 58f1841 c2fa27a ee60524 c2fa27a 58f1841 ee60524 c2fa27a ee60524 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
import gradio as gr
from PIL import Image
import os
from dotenv import load_dotenv
from simple_salesforce import Salesforce
from datetime import datetime
from fastapi import FastAPI, HTTPException, Security, Depends
from fastapi.security import APIKeyHeader
import base64
import io
import random # For mock predictions
# Load environment variables
load_dotenv()
SF_USERNAME = os.getenv("SF_USERNAME")
SF_PASSWORD = os.getenv("SF_PASSWORD")
SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN")
SF_CONSUMER_KEY = os.getenv("SF_CONSUMER_KEY")
SF_CONSUMER_SECRET = os.getenv("SF_CONSUMER_SECRET")
API_KEY = os.getenv("API_KEY", "your-api-key-here")
# Validate Salesforce credentials
if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, SF_CONSUMER_KEY, SF_CONSUMER_SECRET]):
raise ValueError("Missing Salesforce credentials. Set SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, SF_CONSUMER_KEY, and SF_CONSUMER_SECRET in environment variables.")
# Initialize Salesforce connection
try:
sf = Salesforce(
username=SF_USERNAME,
password=SF_PASSWORD,
security_token=SF_SECURITY_TOKEN,
consumer_key=SF_CONSUMER_KEY,
consumer_secret=SF_CONSUMER_SECRET,
domain='login' # Use 'test' for sandbox
)
except Exception as e:
print(f"Salesforce connection failed: {str(e)}")
raise
# FastAPI app for API endpoint
app = FastAPI()
# API Key authentication
api_key_header = APIKeyHeader(name="X-API-Key")
async def verify_api_key(api_key: str = Security(api_key_header)):
if api_key != API_KEY:
raise HTTPException(status_code=401, detail="Invalid API Key")
return api_key
# Mock AI model for milestone detection (since we can't train a real model here)
def mock_ai_model(image):
# Preprocessing: Resize, normalize (simulated)
img = image.convert("RGB")
max_size = 1024
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
# Feature Extraction and Milestone Detection (simulated)
# In a real scenario, this would use a CNN model trained on construction images
milestones = [
"Foundation Completed",
"Structural Framework Started",
"Walls In Progress",
"Roofing Started",
"Interior Work Started",
"Project Completed"
]
# For this image, based on the concrete pillars and rebar, we assume "Structural Framework Started"
milestone = "Structural Framework Started"
completion_percent = 30 # Estimated based on the image
confidence_score = round(random.uniform(0.85, 0.95), 2) # Random confidence between 85-95%
return milestone, completion_percent, confidence_score
@app.post("/predict-milestone")
async def predict_milestone(payload: dict, api_key: str = Depends(verify_api_key)):
try:
# Validate payload
if "image" not in payload:
raise HTTPException(status_code=400, detail="Image field is required")
# Decode base64 image
image_data = payload["image"]
if image_data.startswith("data:image"):
image_data = image_data.split(",")[1] # Remove data URI prefix
img_bytes = base64.b64decode(image_data)
img = Image.open(io.BytesIO(img_bytes))
# Validate image size (max 20MB)
img_bytes_size = len(img_bytes) / (1024 * 1024)
if img_bytes_size > 20:
raise HTTPException(status_code=400, detail="Image size exceeds 20MB")
# Validate image type
if not img.format.lower() in ["jpeg", "png"]:
raise HTTPException(status_code=400, detail="Only JPG/PNG images are supported")
# Run mock AI model
milestone, percent_complete, confidence_score = mock_ai_model(img)
return {
"milestone": milestone,
"percent_complete": percent_complete,
"confidence_score": confidence_score
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")
# Function for Gradio UI to process the image
def process_image(image, project_name):
try:
# Validate inputs
if image is None:
return "Error: Please upload an image to proceed.", "Pending", "", "", 0
if not project_name:
return "Error: Please enter a project name to proceed.", "Pending", "", "", 0
if not project_name.isalnum():
return "Error: Project name must be alphanumeric (letters and numbers only).", "Pending", "", "", 0
# Open and validate image
img = Image.open(image)
# Validate image size and type
image_size_mb = os.path.getsize(image) / (1024 * 1024)
if image_size_mb > 20:
return "Error: Image size exceeds 20MB.", "Failure", "", "", 0
if not image.lower().endswith(('.jpg', '.jpeg', '.png')):
return "Error: Only JPG/PNG images are supported.", "Failure", "", "", 0
# Run mock AI model
milestone, percent_complete, confidence_score = mock_ai_model(img)
# Update Salesforce record
record = {
"Name": project_name,
"Current_Milestone__c": milestone,
"Completion_Percentage__c": percent_complete,
"Last_Updated_On__c": datetime.now().isoformat(),
"Upload_Status__c": "Success",
"Comments__c": f"AI Prediction: {milestone} with {confidence_score*100}% confidence"
}
try:
query = f"SELECT Id FROM Construction_Project__c WHERE Name = '{project_name}'"
result = sf.query(query)
if result["totalSize"] > 0:
project_id = result["records"][0]["Id"]
sf.Construction_Project__c.update(project_id, record)
else:
sf.Construction_Project__c.create(record)
except Exception as e:
return f"Error: Failed to update Salesforce - {str(e)}", "Failure", "", "", 0
return (
f"Success: Milestone: {milestone}, Completion: {percent_complete}%",
"Success",
milestone,
f"Confidence Score: {confidence_score}",
percent_complete
)
except Exception as e:
return f"Error: {str(e)}", "Failure", "", "", 0
# Gradio interface for testing
with gr.Blocks(css=".gradio-container {background-color: #f0f4f8; font-family: Arial;} .title {color: #2c3e50; font-size: 24px; text-align: center;}") as demo:
gr.Markdown("<h1 class='title'>Construction Milestone Detector</h1>")
project_name = gr.Textbox(label="Project Name", placeholder="Enter project name (e.g., MyHouse)")
image_input = gr.Image(type="filepath", label="Upload Construction Site Photo (JPG/PNG, ≤ 20MB)")
submit_button = gr.Button("Process Image")
output_text = gr.Textbox(label="Result")
upload_status = gr.Textbox(label="Upload Status")
milestone = gr.Textbox(label="Detected Milestone")
confidence = gr.Textbox(label="Confidence Score")
progress = gr.Slider(0, 100, label="Completion Percentage", interactive=False, value=0)
submit_button.click(
fn=process_image,
inputs=[image_input, project_name],
outputs=[output_text, upload_status, milestone, confidence, progress]
)
# Launch the Gradio app
demo.launch() |