Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,6 +4,8 @@ from datetime import datetime
|
|
| 4 |
import pandas as pd
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
from simple_salesforce import Salesforce
|
|
|
|
|
|
|
| 7 |
import gradio as gr
|
| 8 |
from transformers import pipeline
|
| 9 |
|
|
@@ -21,6 +23,16 @@ SF_DOMAIN = os.getenv("SF_DOMAIN", "login")
|
|
| 21 |
# Hugging Face sentiment analysis model
|
| 22 |
sentiment_pipeline = pipeline("sentiment-analysis")
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
# Connect to Salesforce
|
| 25 |
def connect_to_salesforce():
|
| 26 |
try:
|
|
@@ -39,6 +51,7 @@ def connect_to_salesforce():
|
|
| 39 |
# Lookup Vendor ID by Name (assuming Vendor_Name__c references Vendor__c)
|
| 40 |
def get_vendor_id_by_name(sf, vendor_name):
|
| 41 |
try:
|
|
|
|
| 42 |
query = f"SELECT Id FROM Vendor__c WHERE Name = '{vendor_name}' LIMIT 1"
|
| 43 |
result = sf.query(query)
|
| 44 |
if result["totalSize"] > 0:
|
|
@@ -57,13 +70,14 @@ def save_to_salesforce(data):
|
|
| 57 |
return "Salesforce connection failed"
|
| 58 |
try:
|
| 59 |
vendor_name = data["vendor_name_id"]
|
|
|
|
| 60 |
vendor_id = get_vendor_id_by_name(sf, vendor_name)
|
| 61 |
if not vendor_id:
|
| 62 |
return f"Error: No vendor found with name '{vendor_name}'"
|
| 63 |
|
| 64 |
result = sf.Vendor_Performance__c.create({
|
| 65 |
"Vendor_ID__c": int(data["vendor_id"]),
|
| 66 |
-
"Vendor_Name__c": vendor_id,
|
| 67 |
"Score__c": data["score"],
|
| 68 |
"Timeliness_Score__c": data["timeliness_score"],
|
| 69 |
"Issue_Count__c": int(data["issue_score"] / 3),
|
|
@@ -82,7 +96,7 @@ def score_vendor(vendor_id, vendor_name_id, delivery_records, issue_counts, nps_
|
|
| 82 |
if not vendor_id or not vendor_name_id:
|
| 83 |
return {"error": "Vendor ID and Vendor Name are required."}
|
| 84 |
if not (0 <= delivery_records <= 100):
|
| 85 |
-
return {"error": "Delivery
|
| 86 |
if not (0 <= nps_values <= 100):
|
| 87 |
return {"error": "NPS must be 0β100"}
|
| 88 |
|
|
@@ -119,29 +133,26 @@ def format_output(vendor_id, vendor_name_id, delivery_records, issue_counts, nps
|
|
| 119 |
"issue_score", "feedback_score", "evaluation_date", "rationale"
|
| 120 |
]]
|
| 121 |
|
| 122 |
-
# Batch CSV Upload
|
| 123 |
def process_uploaded_file(file):
|
| 124 |
try:
|
| 125 |
-
df = pd.read_csv(file)
|
| 126 |
required = {"vendor_id", "vendor_name_id", "delivery_records", "issue_counts", "nps_values"}
|
| 127 |
if not required.issubset(df.columns):
|
| 128 |
-
return f"Missing required columns: {', '.join(required)}", None
|
| 129 |
results = []
|
| 130 |
for _, row in df.iterrows():
|
| 131 |
res = score_vendor(row["vendor_id"], row["vendor_name_id"], row["delivery_records"], row["issue_counts"], row["nps_values"])
|
| 132 |
if "error" not in res:
|
| 133 |
results.append(res)
|
| 134 |
if not results:
|
| 135 |
-
return "No valid records found", None
|
| 136 |
-
|
| 137 |
"vendor_id", "vendor_name_id", "score", "timeliness_score",
|
| 138 |
"issue_score", "feedback_score", "evaluation_date", "rationale"
|
| 139 |
]]
|
| 140 |
-
output_csv_path = "processed_vendors.csv"
|
| 141 |
-
result_df.to_csv(output_csv_path, index=False)
|
| 142 |
-
return "Batch processed", result_df, output_csv_path
|
| 143 |
except Exception as e:
|
| 144 |
-
return f"Error processing file: {e}", None
|
| 145 |
|
| 146 |
# Gradio UI
|
| 147 |
with gr.Blocks(title="Vendor Performance App") as demo:
|
|
@@ -150,8 +161,8 @@ with gr.Blocks(title="Vendor Performance App") as demo:
|
|
| 150 |
with gr.Tabs():
|
| 151 |
with gr.Tab("Single Vendor"):
|
| 152 |
vendor_id = gr.Textbox(label="Vendor ID")
|
| 153 |
-
vendor_name_id = gr.Textbox(label="Vendor Name")
|
| 154 |
-
delivery = gr.Slider(0, 100, label="Delivery
|
| 155 |
issues = gr.Number(label="Issue Count", minimum=0)
|
| 156 |
nps = gr.Slider(0, 100, label="NPS")
|
| 157 |
|
|
@@ -169,27 +180,20 @@ with gr.Blocks(title="Vendor Performance App") as demo:
|
|
| 169 |
)
|
| 170 |
|
| 171 |
with gr.Tab("Upload CSV"):
|
| 172 |
-
gr.
|
| 173 |
-
file_upload = gr.File(label="Upload CSV", file_types=[".csv"])
|
| 174 |
file_status = gr.Textbox(label="Upload Status")
|
| 175 |
file_result = gr.Dataframe(headers=[
|
| 176 |
"Vendor ID", "Vendor Name", "Score", "Timeliness",
|
| 177 |
"Issues", "Feedback", "Date", "Rationale"
|
| 178 |
])
|
| 179 |
-
download_button = gr.File(label="Download Processed Results as CSV", visible=False)
|
| 180 |
-
|
| 181 |
-
def update_download_button(status, result_df, csv_path):
|
| 182 |
-
if result_df is not None and csv_path:
|
| 183 |
-
return gr.update(visible=True, value=csv_path)
|
| 184 |
-
return gr.update(visible=False)
|
| 185 |
|
| 186 |
-
file_upload.
|
| 187 |
fn=process_uploaded_file,
|
| 188 |
inputs=file_upload,
|
| 189 |
-
outputs=[file_status, file_result
|
| 190 |
-
_js="() => {setTimeout(() => document.querySelector('input[type=\"file\"]').value = '', 0)}"
|
| 191 |
)
|
| 192 |
|
| 193 |
-
# Launch the Gradio app
|
| 194 |
if __name__ == "__main__":
|
| 195 |
-
|
|
|
|
|
|
|
|
|
| 4 |
import pandas as pd
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
from simple_salesforce import Salesforce
|
| 7 |
+
from fastapi import FastAPI
|
| 8 |
+
from fastapi.middleware.cors import CORSMiddleware
|
| 9 |
import gradio as gr
|
| 10 |
from transformers import pipeline
|
| 11 |
|
|
|
|
| 23 |
# Hugging Face sentiment analysis model
|
| 24 |
sentiment_pipeline = pipeline("sentiment-analysis")
|
| 25 |
|
| 26 |
+
# FastAPI app
|
| 27 |
+
app = FastAPI()
|
| 28 |
+
app.add_middleware(
|
| 29 |
+
CORSMiddleware,
|
| 30 |
+
allow_origins=["*"],
|
| 31 |
+
allow_credentials=True,
|
| 32 |
+
allow_methods=["*"],
|
| 33 |
+
allow_headers=["*"],
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
# Connect to Salesforce
|
| 37 |
def connect_to_salesforce():
|
| 38 |
try:
|
|
|
|
| 51 |
# Lookup Vendor ID by Name (assuming Vendor_Name__c references Vendor__c)
|
| 52 |
def get_vendor_id_by_name(sf, vendor_name):
|
| 53 |
try:
|
| 54 |
+
# Query the Vendor__c object (adjust object name if different, e.g., Account)
|
| 55 |
query = f"SELECT Id FROM Vendor__c WHERE Name = '{vendor_name}' LIMIT 1"
|
| 56 |
result = sf.query(query)
|
| 57 |
if result["totalSize"] > 0:
|
|
|
|
| 70 |
return "Salesforce connection failed"
|
| 71 |
try:
|
| 72 |
vendor_name = data["vendor_name_id"]
|
| 73 |
+
# Always look up the vendor ID by name
|
| 74 |
vendor_id = get_vendor_id_by_name(sf, vendor_name)
|
| 75 |
if not vendor_id:
|
| 76 |
return f"Error: No vendor found with name '{vendor_name}'"
|
| 77 |
|
| 78 |
result = sf.Vendor_Performance__c.create({
|
| 79 |
"Vendor_ID__c": int(data["vendor_id"]),
|
| 80 |
+
"Vendor_Name__c": vendor_id, # Use the resolved ID
|
| 81 |
"Score__c": data["score"],
|
| 82 |
"Timeliness_Score__c": data["timeliness_score"],
|
| 83 |
"Issue_Count__c": int(data["issue_score"] / 3),
|
|
|
|
| 96 |
if not vendor_id or not vendor_name_id:
|
| 97 |
return {"error": "Vendor ID and Vendor Name are required."}
|
| 98 |
if not (0 <= delivery_records <= 100):
|
| 99 |
+
return {"error": "Delivery % must be 0β100"}
|
| 100 |
if not (0 <= nps_values <= 100):
|
| 101 |
return {"error": "NPS must be 0β100"}
|
| 102 |
|
|
|
|
| 133 |
"issue_score", "feedback_score", "evaluation_date", "rationale"
|
| 134 |
]]
|
| 135 |
|
| 136 |
+
# Batch CSV Upload
|
| 137 |
def process_uploaded_file(file):
|
| 138 |
try:
|
| 139 |
+
df = pd.read_csv(file.name)
|
| 140 |
required = {"vendor_id", "vendor_name_id", "delivery_records", "issue_counts", "nps_values"}
|
| 141 |
if not required.issubset(df.columns):
|
| 142 |
+
return f"Missing required columns: {', '.join(required)}", None
|
| 143 |
results = []
|
| 144 |
for _, row in df.iterrows():
|
| 145 |
res = score_vendor(row["vendor_id"], row["vendor_name_id"], row["delivery_records"], row["issue_counts"], row["nps_values"])
|
| 146 |
if "error" not in res:
|
| 147 |
results.append(res)
|
| 148 |
if not results:
|
| 149 |
+
return "No valid records found", None
|
| 150 |
+
return "Batch processed", pd.DataFrame(results)[[
|
| 151 |
"vendor_id", "vendor_name_id", "score", "timeliness_score",
|
| 152 |
"issue_score", "feedback_score", "evaluation_date", "rationale"
|
| 153 |
]]
|
|
|
|
|
|
|
|
|
|
| 154 |
except Exception as e:
|
| 155 |
+
return f"Error processing file: {e}", None
|
| 156 |
|
| 157 |
# Gradio UI
|
| 158 |
with gr.Blocks(title="Vendor Performance App") as demo:
|
|
|
|
| 161 |
with gr.Tabs():
|
| 162 |
with gr.Tab("Single Vendor"):
|
| 163 |
vendor_id = gr.Textbox(label="Vendor ID")
|
| 164 |
+
vendor_name_id = gr.Textbox(label="Vendor Name") # Updated label to only expect name
|
| 165 |
+
delivery = gr.Slider(0, 100, label="Delivery %")
|
| 166 |
issues = gr.Number(label="Issue Count", minimum=0)
|
| 167 |
nps = gr.Slider(0, 100, label="NPS")
|
| 168 |
|
|
|
|
| 180 |
)
|
| 181 |
|
| 182 |
with gr.Tab("Upload CSV"):
|
| 183 |
+
file_upload = gr.File(label="Upload CSV (vendor_name_id should contain vendor names)", file_types=[".csv"])
|
|
|
|
| 184 |
file_status = gr.Textbox(label="Upload Status")
|
| 185 |
file_result = gr.Dataframe(headers=[
|
| 186 |
"Vendor ID", "Vendor Name", "Score", "Timeliness",
|
| 187 |
"Issues", "Feedback", "Date", "Rationale"
|
| 188 |
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
+
file_upload.change(
|
| 191 |
fn=process_uploaded_file,
|
| 192 |
inputs=file_upload,
|
| 193 |
+
outputs=[file_status, file_result]
|
|
|
|
| 194 |
)
|
| 195 |
|
|
|
|
| 196 |
if __name__ == "__main__":
|
| 197 |
+
import uvicorn
|
| 198 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|
| 199 |
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|