Spaces:
Sleeping
Sleeping
import os | |
import io | |
import time | |
import json | |
import random | |
import tempfile | |
from datetime import datetime, timedelta | |
import pandas as pd | |
import numpy as np | |
import gradio as gr | |
try: | |
import openai | |
OPENAI_AVAILABLE = True | |
except Exception: | |
OPENAI_AVAILABLE = False | |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') | |
if OPENAI_AVAILABLE and OPENAI_API_KEY: | |
openai.api_key = OPENAI_API_KEY | |
def generate_sample_csv(n=50): | |
base_date = datetime.now() + timedelta(days=7) | |
rows = [] | |
interests = ["Data Engineering", "Machine Learning", "Web Dev", "Cloud", "Product"] | |
channels = ["Organic", "Ads", "Referral", "Partner", "Email Campaign"] | |
for i in range(1, n + 1): | |
name = f"User{i:03d}" | |
email = f"user{i:03d}@example.com" | |
phone = f"+91100000{i:04d}"[-13:] | |
interest = random.choice(interests) | |
channel = random.choice(channels) | |
registered_at = (datetime.now() - timedelta(days=random.randint(0, 14))).strftime('%Y-%m-%d') | |
rows.append({ | |
"id": i, | |
"name": name, | |
"email": email, | |
"phone": phone, | |
"interest": interest, | |
"channel": channel, | |
"registered_at": registered_at | |
}) | |
df = pd.DataFrame(rows) | |
tmpfile = tempfile.NamedTemporaryFile(delete=False, suffix=".csv") | |
df.to_csv(tmpfile.name, index=False) | |
tmpfile.close() | |
return tmpfile.name | |
def load_leads_from_file(fileobj): | |
if fileobj is None: | |
return pd.DataFrame() | |
try: | |
df = pd.read_csv(fileobj) | |
except Exception: | |
fileobj.seek(0) | |
df = pd.read_csv(io.StringIO(fileobj.read().decode('utf-8'))) | |
for col in ["name", "email", "phone", "interest", "registered_at"]: | |
if col not in df.columns: | |
df[col] = "" | |
return df | |
def estimate_attendance_prob(df, event_date=None): | |
df = df.copy() | |
if event_date is None: | |
event_date = datetime.now() + timedelta(days=7) | |
else: | |
if isinstance(event_date, str): | |
event_date = datetime.fromisoformat(event_date) | |
def channel_score(ch): | |
ch = str(ch).lower() | |
if 'ref' in ch: return 0.12 | |
if 'organic' in ch: return 0.08 | |
if 'partner' in ch: return 0.10 | |
if 'email' in ch: return 0.06 | |
return 0.03 | |
interest_map = { | |
'Data Engineering': 0.12, | |
'Machine Learning': 0.11, | |
'Web Dev': 0.07, | |
'Cloud': 0.09, | |
'Product': 0.06 | |
} | |
probs = [] | |
for _, r in df.iterrows(): | |
try: | |
reg = datetime.fromisoformat(str(r.get('registered_at'))) | |
except Exception: | |
reg = datetime.now() | |
days_until = (event_date - reg).days | |
if days_until <= 0: | |
base = 0.25 | |
elif days_until <= 2: | |
base = 0.22 | |
elif days_until <= 7: | |
base = 0.18 | |
else: | |
base = 0.12 | |
ch_boost = channel_score(r.get('channel', '')) | |
interest_boost = interest_map.get(r.get('interest'), 0.05) | |
noise = random.uniform(-0.03, 0.03) | |
p = base + ch_boost + interest_boost + noise | |
p = max(0.01, min(0.95, p)) | |
probs.append(round(p, 3)) | |
df['predicted_prob'] = probs | |
return df | |
def generate_personalized_message(row, event_name="Scaler Live: Roadmap to Data Engineering", event_date=None, use_openai=False): | |
if event_date is None: | |
event_date = (datetime.now() + timedelta(days=7)).strftime('%b %d, %Y') | |
name = row.get('name', 'there') | |
interest = row.get('interest', '') | |
prob = row.get('predicted_prob', None) | |
if use_openai and OPENAI_AVAILABLE and OPENAI_API_KEY: | |
prompt = f"Write a short personalized reminder message (1-2 sentences) for {name} who is interested in {interest} to attend the online event '{event_name}' on {event_date}. Make it friendly and include a single call-to-action 'Join here: <link>'." | |
try: | |
resp = openai.Completion.create( | |
engine='text-davinci-003', | |
prompt=prompt, | |
max_tokens=80, | |
temperature=0.7, | |
n=1 | |
) | |
return resp.choices[0].text.strip() | |
except Exception: | |
pass | |
urgency = "Don't miss out!" if (prob is not None and prob < 0.25) else "Can't wait to see you there!" | |
return f"Hi {name},\nWe have a short live session '{event_name}' on {event_date} that covers {interest} topics you care about. {urgency} Join here: <join-link>" | |
def batch_generate_messages(df, event_name, event_date, use_openai=False): | |
df = df.copy() | |
messages = [] | |
for _, r in df.iterrows(): | |
msg = generate_personalized_message(r, event_name=event_name, event_date=event_date, use_openai=use_openai) | |
messages.append(msg) | |
df['message'] = messages | |
return df | |
def simulate_send_campaign(df, channel='email'): | |
sent_rows = [] | |
opens = 0 | |
clicks = 0 | |
for _, r in df.iterrows(): | |
p = float(r.get('predicted_prob', 0.1)) | |
open_prob = min(0.9, 0.2 + p * 0.6) | |
click_prob = min(0.8, 0.05 + p * 0.5) | |
opened = random.random() < open_prob | |
clicked = opened and (random.random() < click_prob) | |
sent_rows.append({ | |
'id': r.get('id'), | |
'name': r.get('name'), | |
'email': r.get('email'), | |
'phone': r.get('phone'), | |
'predicted_prob': r.get('predicted_prob'), | |
'opened': opened, | |
'clicked': clicked, | |
'message': r.get('message') | |
}) | |
opens += int(opened) | |
clicks += int(clicked) | |
sent_df = pd.DataFrame(sent_rows) | |
stats = { | |
'total_sent': len(sent_df), | |
'opens': int(opens), | |
'clicks': int(clicks), | |
'open_rate': round(opens / max(1, len(sent_df)), 3), | |
'click_rate': round(clicks / max(1, len(sent_df)), 3) | |
} | |
out_path = '/mnt/data/simulated_sent_log.csv' | |
try: | |
sent_df.to_csv(out_path, index=False) | |
except Exception: | |
pass | |
return stats, sent_df | |
def ui_generate_sample_csv(n=50): | |
return generate_sample_csv(n) | |
def ui_load_and_preview(file): | |
if file is None: | |
return pd.DataFrame() | |
df = load_leads_from_file(file) | |
df = estimate_attendance_prob(df) | |
return df | |
def ui_estimate_and_generate(df, event_name, event_date, use_openai=False): | |
if isinstance(df, str): | |
df = pd.read_csv(io.StringIO(df)) | |
if df is None or len(df) == 0: | |
return pd.DataFrame(), "No leads provided" | |
df = estimate_attendance_prob(df, event_date=event_date) | |
df = batch_generate_messages(df, event_name, event_date, use_openai=use_openai) | |
return df, f"Generated messages and probabilities for {len(df)} leads" | |
def ui_simulate_send(df): | |
if isinstance(df, str): | |
df = pd.read_csv(io.StringIO(df)) | |
stats, sent_df = simulate_send_campaign(df) | |
return stats, sent_df | |
def ui_export_csv(df): | |
if isinstance(df, str): | |
df = pd.read_csv(io.StringIO(df)) | |
tmpfile = tempfile.NamedTemporaryFile(delete=False, suffix=".csv") | |
df.to_csv(tmpfile.name, index=False) | |
tmpfile.close() | |
return tmpfile.name | |
with gr.Blocks(title="AI Conversion Automator - Scaler APM MVP") as demo: | |
gr.Markdown("# AI Conversion Automator β Increase joining % for free live class") | |
with gr.Tab("1. Sample CSV"): | |
with gr.Row(): | |
n_samples = gr.Slider(minimum=10, maximum=500, value=50, label="Number of sample leads") | |
gen_btn = gr.Button("Generate sample CSV") | |
sample_download = gr.File() | |
gen_btn.click(fn=ui_generate_sample_csv, inputs=[n_samples], outputs=[sample_download]) | |
with gr.Tab("2. Upload & Preview Leads"): | |
uploader = gr.File(label="Upload leads CSV (columns: id,name,email,phone,interest,channel,registered_at)") | |
preview = gr.Dataframe(headers=None, row_count=10) | |
load_btn = gr.Button("Load & Preview") | |
load_btn.click(fn=ui_load_and_preview, inputs=[uploader], outputs=[preview]) | |
with gr.Tab("3. Generate Messages & Predictions"): | |
event_name = gr.Textbox(label="Event name", value="Roadmap to Data Engineering β Live Class") | |
event_date = gr.Textbox(label="Event date (YYYY-MM-DD)", value=(datetime.now() + timedelta(days=7)).strftime('%Y-%m-%d')) | |
use_openai = gr.Checkbox(label="Use OpenAI for message generation (requires OPENAI_API_KEY)", value=False) | |
generate_btn = gr.Button("Generate Messages & Probabilities") | |
generated_table = gr.Dataframe(headers=None, row_count=20) | |
status_txt = gr.Textbox(label="Status") | |
generate_btn.click(fn=ui_estimate_and_generate, inputs=[preview, event_name, event_date, use_openai], outputs=[generated_table, status_txt]) | |
with gr.Tab("4. Simulate Campaign"): | |
simulate_btn = gr.Button("Simulate Send") | |
sim_stats = gr.JSON() | |
sim_table = gr.Dataframe(headers=None, row_count=20) | |
simulate_btn.click(fn=ui_simulate_send, inputs=[generated_table], outputs=[sim_stats, sim_table]) | |
with gr.Tab("5. Export"): | |
export_btn = gr.Button("Export CSV") | |
download_file = gr.File() | |
export_btn.click(fn=ui_export_csv, inputs=[generated_table], outputs=[download_file]) | |
if __name__ == '__main__': | |
demo.launch() | |