IAMTFRMZA's picture
Update app.py
29997ba verified
import gradio as gr
import openai
import json
import os
import re
# Set your OpenAI API key
openai.api_key = os.getenv("OPENAI_API_KEY")
# OpenAI Assistant ID
ASSISTANT_ID = "asst_mDU549QCoU616nB69g5ZwI58"
# Load full product catalog
with open("cleaned_product_catalog.json", "r") as f:
PRODUCT_CATALOG = {item["ProductCode"]: item for item in json.load(f)}
# Global session state
cart = []
thread_id = None
# 🧠 Smart JSON extractor that handles both ```json``` and loose JSON objects
def extract_cart_json_from_text(text):
blocks = []
# 1. Try to find ```json ... ``` blocks
code_blocks = re.findall(r"```json(.*?)```", text, re.DOTALL)
for block in code_blocks:
try:
blocks.append(json.loads(block.strip()))
except Exception:
continue
# 2. Fall back to finding any JSON-like objects
if not blocks:
loose_jsons = re.findall(r"\{[\s\S]+?\}", text)
for snippet in loose_jsons:
try:
candidate = json.loads(snippet)
if "ProductCode" in candidate and "Description" in candidate:
blocks.append(candidate)
except Exception:
continue
return blocks
# 🔄 Communicate with OpenAI Assistant
def send_to_assistant(message):
global thread_id
if thread_id is None:
thread = openai.beta.threads.create()
thread_id = thread.id
openai.beta.threads.messages.create(
thread_id=thread_id,
role="user",
content=message
)
run = openai.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=ASSISTANT_ID
)
while True:
run_status = openai.beta.threads.runs.retrieve(
thread_id=thread_id,
run_id=run.id
)
if run_status.status == "completed":
break
messages = openai.beta.threads.messages.list(thread_id=thread_id)
return messages.data[0].content[0].text.value
# 📦 Handle chat + add to cart
def assistant_response(message, chat_history):
global cart
response = send_to_assistant(message)
extracted_items = extract_cart_json_from_text(response)
if extracted_items:
for item in extracted_items:
cart.append(item)
chat_history.append((message, response))
return "", chat_history, json.dumps(cart, indent=2)
# 🧼 Clear cart
def clear_cart():
global cart
cart.clear()
return json.dumps(cart, indent=2)
# ✅ Finalise order
def submit_order():
global cart
if not cart:
return "No items in cart, mate!"
customer = cart[0].get("Customer", {}) if cart else {}
discount_rate = customer.get("Discount", 0)
# Safe subtotal calc
subtotal = 0
for item in cart:
try:
price = float(item["Price"])
except:
price = 0.0
subtotal += price * item.get("Quantity", 1)
discount_amt = round(subtotal * discount_rate, 2)
total = round(subtotal - discount_amt, 2)
# Save final order
order_summary = {
"Customer": customer,
"Products": [
{k: v for k, v in item.items() if k != "Customer"}
for item in cart
],
"Totals": {
"Subtotal": round(subtotal, 2),
"DiscountRate": discount_rate,
"DiscountAmount": discount_amt,
"TotalAfterDiscount": total
}
}
with open("order_summary.json", "w") as f:
json.dump(order_summary, f, indent=2)
# Generate friendly summary
response_text = f"✅ Sweet as, {customer.get('Name', 'mate')} — your order’s locked in!\n\nHere’s what’s in the kit:\n\n"
for item in cart:
response_text += f"- {item['ProductCode']}{item['Description']} — 💰 ${item['Price']}\n"
response_text += f"\n💲 **Subtotal:** ${subtotal:.2f}\n"
response_text += f"🎯 **Discount ({int(discount_rate*100)}%):** -${discount_amt:.2f}\n"
response_text += f"✅ **Total After Discount:** ${total:.2f}\n\n"
response_text += "We’ll get this sorted faster than a roo in a paddock. You’ll hear from us soon!"
cart.clear()
return response_text
# 🖼️ Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("# 🧢 Westate Sales Assistant 🇦🇺\nTalk to your hose mate and build your order!")
with gr.Row():
with gr.Column(scale=3):
chatbot = gr.Chatbot()
msg = gr.Textbox(label="Type your question here", placeholder="Ask Willy anything...")
send = gr.Button("Send")
with gr.Column(scale=2):
cart_display = gr.Textbox(label="🛒 Cart (Full JSON)", lines=20)
clear_btn = gr.Button("Clear Cart")
checkout_btn = gr.Button("Checkout")
send.click(assistant_response, inputs=[msg, chatbot], outputs=[msg, chatbot, cart_display])
clear_btn.click(fn=clear_cart, outputs=cart_display)
checkout_btn.click(fn=submit_order, outputs=cart_display)
demo.launch()