app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import faiss
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
|
| 7 |
+
client = OpenAI()
|
| 8 |
+
|
| 9 |
+
def row_to_text(row):
|
| 10 |
+
return (
|
| 11 |
+
f"Clinic: {row['Account_Name']}\n"
|
| 12 |
+
f"Region: {row['Region']}\n"
|
| 13 |
+
f"Account Manager: {row['Account_Manager']}\n"
|
| 14 |
+
f"Revenue: €{row['Revenue']}\n"
|
| 15 |
+
f"Last Purchase: {row['Last_Purchase_Date']}\n"
|
| 16 |
+
f"Churn Risk: {row['Churn_Risk']}\n"
|
| 17 |
+
f"Satisfaction Score: {row['Satisfaction_Score']}/10\n"
|
| 18 |
+
f"Product Interest: {row['Product_Interest']}\n"
|
| 19 |
+
f"Notes: {row['Account_Notes']}"
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
def get_embedding(text):
|
| 23 |
+
response = client.embeddings.create(
|
| 24 |
+
input=[text],
|
| 25 |
+
model="text-embedding-3-small"
|
| 26 |
+
)
|
| 27 |
+
return response.data[0].embedding
|
| 28 |
+
|
| 29 |
+
def contextual_pitch_assistant(csv_file, query):
|
| 30 |
+
df = pd.read_csv(csv_file.name)
|
| 31 |
+
text_chunks = df.apply(row_to_text, axis=1).tolist()
|
| 32 |
+
embeddings = [get_embedding(t) for t in text_chunks]
|
| 33 |
+
|
| 34 |
+
dim = len(embeddings[0])
|
| 35 |
+
index = faiss.IndexFlatL2(dim)
|
| 36 |
+
index.add(np.array(embeddings).astype('float32'))
|
| 37 |
+
|
| 38 |
+
q_emb = np.array([get_embedding(query)]).astype('float32')
|
| 39 |
+
D, I = index.search(q_emb, 3)
|
| 40 |
+
retrieved = [text_chunks[i] for i in I[0]]
|
| 41 |
+
|
| 42 |
+
prompt = f"""
|
| 43 |
+
You are an expert in B2B sales and digital pitching for dental clinics.
|
| 44 |
+
Based on the following CRM insights and query, generate:
|
| 45 |
+
1) A short HTML email pitch (subject + body) ready to send.
|
| 46 |
+
2) A DALL·E 3 prompt for a matching header image.
|
| 47 |
+
|
| 48 |
+
Query:
|
| 49 |
+
{query}
|
| 50 |
+
|
| 51 |
+
CRM data:
|
| 52 |
+
{'---'.join(retrieved)}
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
response = client.chat.completions.create(
|
| 56 |
+
model="gpt-4o-mini",
|
| 57 |
+
messages=[{"role": "user", "content": prompt}],
|
| 58 |
+
temperature=0.7
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
output_text = response.choices[0].message.content
|
| 62 |
+
|
| 63 |
+
import re
|
| 64 |
+
match = re.search(r"(Image prompt|DALL·E prompt)[:\-]\s*(.*)", output_text)
|
| 65 |
+
image_prompt = match.group(2).strip() if match else "modern dental clinic interior with dentist and patient"
|
| 66 |
+
|
| 67 |
+
image = client.images.generate(
|
| 68 |
+
model="gpt-image-1",
|
| 69 |
+
prompt=image_prompt,
|
| 70 |
+
size="1024x1024"
|
| 71 |
+
)
|
| 72 |
+
image_url = image.data[0].url
|
| 73 |
+
|
| 74 |
+
html = f"""
|
| 75 |
+
<div style='font-family:Arial,sans-serif;max-width:600px;margin:auto;padding:16px;background:#ffffff;
|
| 76 |
+
border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,0.1);'>
|
| 77 |
+
<img src="{image_url}" style="width:100%;border-radius:8px;margin-bottom:16px;">
|
| 78 |
+
{output_text}
|
| 79 |
+
</div>
|
| 80 |
+
"""
|
| 81 |
+
return html
|
| 82 |
+
|
| 83 |
+
app = gr.Interface(
|
| 84 |
+
fn=contextual_pitch_assistant,
|
| 85 |
+
inputs=[
|
| 86 |
+
gr.File(label="Upload CRM CSV (5–100 rows)", file_types=[".csv"]),
|
| 87 |
+
gr.Textbox(label="Sales Query", placeholder="e.g. Which clinic is best for our imaging subscription?")
|
| 88 |
+
],
|
| 89 |
+
outputs=gr.HTML(label="Email Pitch Preview"),
|
| 90 |
+
title="Contextual Pitch Assistant for Dental Sales",
|
| 91 |
+
description="Upload CRM data and get a personalized contextual pitch with generated imagery."
|
| 92 |
+
)
|
| 93 |
+
|
| 94 |
+
app.launch()
|