Update app.py
Browse files
app.py
CHANGED
|
@@ -3,10 +3,10 @@ from paddleocr import PaddleOCR
|
|
| 3 |
from PIL import Image
|
| 4 |
import gradio as gr
|
| 5 |
import re
|
| 6 |
-
|
| 7 |
import pandas as pd
|
| 8 |
|
| 9 |
-
# Attribute mappings: readable names to Salesforce API names
|
| 10 |
ATTRIBUTE_MAPPING = {
|
| 11 |
"Name": "Name__c",
|
| 12 |
"Age": "Age__c",
|
|
@@ -21,18 +21,18 @@ ATTRIBUTE_ORDER = ["Name", "Age", "Gender", "Phone Number"]
|
|
| 21 |
GENDER_MAPPING = {
|
| 22 |
"Male": "Male",
|
| 23 |
"Female": "Female",
|
| 24 |
-
"Other": "Others" # Map 'Other' to 'Others' to match picklist
|
| 25 |
}
|
| 26 |
|
| 27 |
-
# Salesforce credentials
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
|
| 32 |
# Initialize PaddleOCR
|
| 33 |
ocr = PaddleOCR(use_angle_cls=True, lang='en')
|
| 34 |
|
| 35 |
-
# Function to extract text using PaddleOCR
|
| 36 |
def extract_text(image):
|
| 37 |
result = ocr.ocr(image)
|
| 38 |
extracted_text = []
|
|
@@ -40,16 +40,16 @@ def extract_text(image):
|
|
| 40 |
extracted_text.append(line[1][0])
|
| 41 |
return "\n".join(extracted_text)
|
| 42 |
|
| 43 |
-
# Function to extract attributes
|
| 44 |
def extract_attributes(extracted_text):
|
| 45 |
attributes = {}
|
| 46 |
|
| 47 |
# Patterns for extracting personal information
|
| 48 |
patterns = {
|
| 49 |
-
"Name": r"Name[:\-]?\s*([A-Za-z]+)", #
|
| 50 |
-
"Age": r"Age[:\-]?\s*(\d{1,3})",
|
| 51 |
-
"Gender": r"Gender[:\-]?\s*(Male|Female|Other)",
|
| 52 |
-
"Phone Number": r"(?:(?:Phone Number)|Phone|Mobile|Phonenumber)[:\-]?\s*(?:\+91)?([6-9]\d{9})"
|
| 53 |
}
|
| 54 |
|
| 55 |
for readable_attr, pattern in patterns.items():
|
|
@@ -57,47 +57,59 @@ def extract_attributes(extracted_text):
|
|
| 57 |
if match:
|
| 58 |
attributes[readable_attr] = match.group(1).strip()
|
| 59 |
|
| 60 |
-
# Map Gender to picklist values
|
| 61 |
if "Gender" in attributes:
|
| 62 |
attributes["Gender"] = GENDER_MAPPING.get(attributes["Gender"], attributes["Gender"])
|
| 63 |
|
| 64 |
return attributes
|
| 65 |
|
| 66 |
-
# Function to filter attributes for valid Salesforce fields
|
| 67 |
-
def filter_valid_attributes(attributes, valid_fields
|
| 68 |
-
# Mock valid fields since Salesforce is disabled
|
| 69 |
-
if valid_fields is None:
|
| 70 |
-
valid_fields = {"Name", "Name__c", "Age__c", "Gender__c", "Phone_Number__c"}
|
| 71 |
-
|
| 72 |
filtered = {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
|
| 73 |
|
| 74 |
-
# Add the standard 'Name' field
|
| 75 |
if "Name" in attributes and "Name" in valid_fields:
|
| 76 |
filtered["Name"] = attributes["Name"]
|
| 77 |
|
| 78 |
return filtered
|
| 79 |
|
| 80 |
-
# Function to
|
| 81 |
def interact_with_salesforce(attributes):
|
| 82 |
try:
|
| 83 |
-
#
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
filtered_attributes = filter_valid_attributes(attributes, valid_fields)
|
| 86 |
|
| 87 |
-
# Log the attributes
|
| 88 |
-
print(f"Attributes
|
| 89 |
|
| 90 |
-
# Ensure Age__c is a number (for
|
| 91 |
if "Age__c" in filtered_attributes:
|
| 92 |
filtered_attributes["Age__c"] = int(filtered_attributes["Age__c"])
|
| 93 |
|
| 94 |
-
#
|
| 95 |
-
|
|
|
|
| 96 |
|
| 97 |
except Exception as e:
|
| 98 |
-
return f"❌ Error
|
| 99 |
|
| 100 |
-
# Function to process image and extract attributes
|
| 101 |
def process_image(image):
|
| 102 |
extracted_text = extract_text(image)
|
| 103 |
if not extracted_text:
|
|
@@ -108,22 +120,22 @@ def process_image(image):
|
|
| 108 |
# Ensure all attributes are present, even if empty, in the desired order
|
| 109 |
ordered_attributes = {attr: attributes.get(attr, "") for attr in ATTRIBUTE_ORDER}
|
| 110 |
|
| 111 |
-
# Convert attributes to DataFrame
|
| 112 |
df = pd.DataFrame(list(ordered_attributes.items()), columns=["Attribute", "Value"])
|
| 113 |
return f"Extracted Text:\n{extracted_text}", df, None
|
| 114 |
|
| 115 |
-
# Function to handle edited attributes and export to Salesforce
|
| 116 |
def export_to_salesforce(edited_df):
|
| 117 |
try:
|
| 118 |
# Convert edited DataFrame back to dictionary
|
| 119 |
edited_attributes = dict(zip(edited_df["Attribute"], edited_df["Value"]))
|
| 120 |
|
| 121 |
-
# Export to Salesforce
|
| 122 |
message = interact_with_salesforce(edited_attributes)
|
| 123 |
return message
|
| 124 |
|
| 125 |
except Exception as e:
|
| 126 |
-
return f"❌ Error exporting
|
| 127 |
|
| 128 |
# Gradio Interface
|
| 129 |
def app():
|
|
|
|
| 3 |
from PIL import Image
|
| 4 |
import gradio as gr
|
| 5 |
import re
|
| 6 |
+
from simple_salesforce import Salesforce
|
| 7 |
import pandas as pd
|
| 8 |
|
| 9 |
+
# Attribute mappings: readable names to Salesforce API names
|
| 10 |
ATTRIBUTE_MAPPING = {
|
| 11 |
"Name": "Name__c",
|
| 12 |
"Age": "Age__c",
|
|
|
|
| 21 |
GENDER_MAPPING = {
|
| 22 |
"Male": "Male",
|
| 23 |
"Female": "Female",
|
| 24 |
+
"Other": "Others" # Map 'Other' to 'Others' to match Salesforce picklist
|
| 25 |
}
|
| 26 |
|
| 27 |
+
# Salesforce credentials
|
| 28 |
+
SALESFORCE_USERNAME = "sathkruthatech@hms.com"
|
| 29 |
+
SALESFORCE_PASSWORD = "Hms@2025"
|
| 30 |
+
SALESFORCE_SECURITY_TOKEN = "5W0grf0aX0M9cD3yDZ2C5F"
|
| 31 |
|
| 32 |
# Initialize PaddleOCR
|
| 33 |
ocr = PaddleOCR(use_angle_cls=True, lang='en')
|
| 34 |
|
| 35 |
+
# Function to extract text from an image using PaddleOCR
|
| 36 |
def extract_text(image):
|
| 37 |
result = ocr.ocr(image)
|
| 38 |
extracted_text = []
|
|
|
|
| 40 |
extracted_text.append(line[1][0])
|
| 41 |
return "\n".join(extracted_text)
|
| 42 |
|
| 43 |
+
# Function to extract attributes using regex
|
| 44 |
def extract_attributes(extracted_text):
|
| 45 |
attributes = {}
|
| 46 |
|
| 47 |
# Patterns for extracting personal information
|
| 48 |
patterns = {
|
| 49 |
+
"Name": r"Name[:\-]?\s*([A-Za-z]+)", # Extracts names without spaces
|
| 50 |
+
"Age": r"Age[:\-]?\s*(\d{1,3})", # Extracts 1-3 digit age
|
| 51 |
+
"Gender": r"Gender[:\-]?\s*(Male|Female|Other)", # Extracts Male, Female, or Other
|
| 52 |
+
"Phone Number": r"(?:(?:Phone Number)|Phone|Mobile|Phonenumber)[:\-]?\s*(?:\+91)?([6-9]\d{9})" # Indian phone number: 10 digits, starts with 6-9
|
| 53 |
}
|
| 54 |
|
| 55 |
for readable_attr, pattern in patterns.items():
|
|
|
|
| 57 |
if match:
|
| 58 |
attributes[readable_attr] = match.group(1).strip()
|
| 59 |
|
| 60 |
+
# Map Gender to Salesforce picklist values
|
| 61 |
if "Gender" in attributes:
|
| 62 |
attributes["Gender"] = GENDER_MAPPING.get(attributes["Gender"], attributes["Gender"])
|
| 63 |
|
| 64 |
return attributes
|
| 65 |
|
| 66 |
+
# Function to filter attributes for valid Salesforce fields
|
| 67 |
+
def filter_valid_attributes(attributes, valid_fields):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
filtered = {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
|
| 69 |
|
| 70 |
+
# Add the standard 'Name' field (required by Salesforce for custom objects)
|
| 71 |
if "Name" in attributes and "Name" in valid_fields:
|
| 72 |
filtered["Name"] = attributes["Name"]
|
| 73 |
|
| 74 |
return filtered
|
| 75 |
|
| 76 |
+
# Function to create a record in Salesforce
|
| 77 |
def interact_with_salesforce(attributes):
|
| 78 |
try:
|
| 79 |
+
# Initialize Salesforce connection
|
| 80 |
+
sf = Salesforce(
|
| 81 |
+
username=SALESFORCE_USERNAME,
|
| 82 |
+
password=SALESFORCE_PASSWORD,
|
| 83 |
+
security_token=SALESFORCE_SECURITY_TOKEN,
|
| 84 |
+
domain="test" # Sandbox instance
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
# Reference the Patient_Registration__c object
|
| 88 |
+
object_name = "Patient_Registration__c"
|
| 89 |
+
sf_object = sf.__getattr__(object_name)
|
| 90 |
+
|
| 91 |
+
# Get the object's schema to validate fields
|
| 92 |
+
schema = sf_object.describe()
|
| 93 |
+
valid_fields = {field["name"] for field in schema["fields"]}
|
| 94 |
+
|
| 95 |
+
# Filter attributes to match valid Salesforce fields
|
| 96 |
filtered_attributes = filter_valid_attributes(attributes, valid_fields)
|
| 97 |
|
| 98 |
+
# Log the attributes being sent for debugging
|
| 99 |
+
print(f"Attributes being sent to Salesforce: {filtered_attributes}")
|
| 100 |
|
| 101 |
+
# Ensure Age__c is a number (Salesforce expects an integer for this field)
|
| 102 |
if "Age__c" in filtered_attributes:
|
| 103 |
filtered_attributes["Age__c"] = int(filtered_attributes["Age__c"])
|
| 104 |
|
| 105 |
+
# Create the record in Salesforce
|
| 106 |
+
result = sf_object.create(filtered_attributes)
|
| 107 |
+
return f"✅ Successfully created Patient Registration record with ID: {result['id']}."
|
| 108 |
|
| 109 |
except Exception as e:
|
| 110 |
+
return f"❌ Error interacting with Salesforce: {str(e)}"
|
| 111 |
|
| 112 |
+
# Function to process the image and extract attributes
|
| 113 |
def process_image(image):
|
| 114 |
extracted_text = extract_text(image)
|
| 115 |
if not extracted_text:
|
|
|
|
| 120 |
# Ensure all attributes are present, even if empty, in the desired order
|
| 121 |
ordered_attributes = {attr: attributes.get(attr, "") for attr in ATTRIBUTE_ORDER}
|
| 122 |
|
| 123 |
+
# Convert attributes to DataFrame for display
|
| 124 |
df = pd.DataFrame(list(ordered_attributes.items()), columns=["Attribute", "Value"])
|
| 125 |
return f"Extracted Text:\n{extracted_text}", df, None
|
| 126 |
|
| 127 |
+
# Function to handle edited attributes and export to Salesforce
|
| 128 |
def export_to_salesforce(edited_df):
|
| 129 |
try:
|
| 130 |
# Convert edited DataFrame back to dictionary
|
| 131 |
edited_attributes = dict(zip(edited_df["Attribute"], edited_df["Value"]))
|
| 132 |
|
| 133 |
+
# Export to Salesforce
|
| 134 |
message = interact_with_salesforce(edited_attributes)
|
| 135 |
return message
|
| 136 |
|
| 137 |
except Exception as e:
|
| 138 |
+
return f"❌ Error exporting to Salesforce: {str(e)}"
|
| 139 |
|
| 140 |
# Gradio Interface
|
| 141 |
def app():
|