aunghlaing commited on
Commit
bc43369
·
verified ·
1 Parent(s): d5c56ed

Create UI3

Browse files
Files changed (1) hide show
  1. appwithSendgrid.py +191 -0
appwithSendgrid.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import torch
4
+ import sqlite3
5
+ from datetime import datetime
6
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
7
+ from huggingface_hub import snapshot_download
8
+ from sendgrid import SendGridAPIClient
9
+ from sendgrid.helpers.mail import Mail
10
+
11
+ # Student Information
12
+ My_info = "Student ID: 6319250G, Name: Aung Hlaing Tun"
13
+
14
+ # Define Hugging Face Model Repo
15
+ MODEL_REPO_ID = "ZAM-ITI-110/Distil_Bert_V3"
16
+
17
+ # SendGrid API Key (Set in Hugging Face Space Secrets)
18
+ SENDGRID_API_KEY = os.getenv("SENDGRID_API_KEY") # Add this in Space Settings > Secrets
19
+
20
+ # Load Model & Tokenizer from Hugging Face
21
+ def load_model(repo_id):
22
+ """Download and load the model and tokenizer."""
23
+ cache_dir = "/home/user/app/hf_models"
24
+ os.makedirs(cache_dir, exist_ok=True)
25
+ download_dir = snapshot_download(repo_id, cache_dir=cache_dir, local_files_only=False)
26
+ model = AutoModelForSequenceClassification.from_pretrained(download_dir)
27
+ tokenizer = AutoTokenizer.from_pretrained(download_dir)
28
+ return model, tokenizer
29
+
30
+ # Load Model
31
+ model, tokenizer = load_model(MODEL_REPO_ID)
32
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
33
+ model.to(device)
34
+ model.eval()
35
+
36
+ # Initialize SQLite Database
37
+ def init_db():
38
+ """Create the tickets table if it doesn’t exist."""
39
+ conn = sqlite3.connect("tickets.db")
40
+ c = conn.cursor()
41
+ c.execute('''CREATE TABLE IF NOT EXISTS tickets
42
+ (id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT, predicted_team TEXT,
43
+ team_email TEXT, status TEXT, timestamp TEXT)''')
44
+ conn.commit()
45
+ conn.close()
46
+
47
+ # Prediction Function (Single Ticket)
48
+ def predict_team_and_email(text):
49
+ """Predict team and email for a single ticket description."""
50
+ if not text.strip():
51
+ return "", ""
52
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True).to(device)
53
+ with torch.no_grad():
54
+ logits = model(**inputs).logits
55
+ pred = torch.argmax(logits, dim=-1).item()
56
+
57
+ label_mapping = {
58
+ 0: "Code Review Team", 1: "Functional Team", 2: "Infrastructure Team",
59
+ 3: "Performance Team", 4: "Security Team"
60
+ }
61
+ email_mapping = {
62
63
64
65
+ }
66
+
67
+ return label_mapping.get(pred, "Unknown"), email_mapping.get(pred, "Unknown")
68
+
69
+ # Save Ticket to Database
70
+ def save_ticket(description, predicted_team, team_email):
71
+ """Save a ticket to the SQLite database."""
72
+ conn = sqlite3.connect("tickets.db")
73
+ c = conn.cursor()
74
+ c.execute("INSERT INTO tickets (description, predicted_team, team_email, status, timestamp) VALUES (?, ?, ?, ?, ?)",
75
+ (description, predicted_team, team_email, "Open", datetime.now().isoformat()))
76
+ conn.commit()
77
+ conn.close()
78
+
79
+ # Send Email via SendGrid
80
+ def send_email(to_email, subject, content):
81
+ """Send an email using SendGrid."""
82
+ if not SENDGRID_API_KEY:
83
+ return "SendGrid API key not set."
84
+ message = Mail(
85
+ from_email="[email protected]", # Replace with your verified sender email
86
+ to_emails=to_email,
87
+ subject=subject,
88
+ plain_text_content=content)
89
+ try:
90
+ sg = SendGridAPIClient(SENDGRID_API_KEY)
91
+ sg.send(message)
92
+ return "Email sent successfully!"
93
+ except Exception as e:
94
+ return f"Email failed: {str(e)}"
95
+
96
+ # Send Tickets Function
97
+ def send_tickets(*args):
98
+ """Save to DB and send emails for non-empty tickets."""
99
+ tickets = []
100
+ for i, (text, team, email) in enumerate(zip(args[::2], args[1::2], args[2::2]), 1):
101
+ if text.strip() and team and email:
102
+ save_ticket(text, team, email)
103
+ email_status = send_email(email, f"New Ticket Assigned to {team}", text)
104
+ tickets.append(f"Ticket {i}: '{text}' -> {team} ({email}) - {email_status}")
105
+ return "\n".join(tickets) + "\n\nProcessed successfully!" if tickets else "No tickets to send."
106
+
107
+ # Clear Function
108
+ def clear_all():
109
+ """Clear all inputs and outputs."""
110
+ return [""] * 19 # 6 tickets x (input, team, email) + 1 sent_output
111
+
112
+ # Fetch Ticket History
113
+ def get_ticket_history():
114
+ """Retrieve all tickets from the database."""
115
+ conn = sqlite3.connect("tickets.db")
116
+ df = pd.read_sql_query("SELECT * FROM tickets", conn)
117
+ conn.close()
118
+ return df
119
+
120
+ # Gradio UI Setup
121
+ init_db() # Initialize database on startup
122
+ with gr.Blocks(title="AI Ticket Classifier") as interface:
123
+ gr.Markdown("📩 **Development of an AI Ticket Classifier Model Using DistilBERT**")
124
+ gr.Markdown(f"*{My_info}*")
125
+ gr.Markdown(
126
+ """
127
+ **🔍 About this App**
128
+ - Predicts the appropriate **team** and **email** for up to 6 ticket descriptions.
129
+ - Click 'Predict' for each ticket, then 'Send Tickets' to save and notify teams.
130
+ """
131
+ )
132
+
133
+ # Ticket Entry Section
134
+ with gr.Column():
135
+ gr.Markdown("### Enter Ticket Descriptions")
136
+ inputs = []
137
+ outputs = []
138
+ buttons = []
139
+ for i in range(6):
140
+ with gr.Row():
141
+ ticket_input = gr.Textbox(lines=2, placeholder=f"Ticket {i+1} description...", label=f"Ticket {i+1}")
142
+ team_output = gr.Textbox(label="Predicted Team", interactive=False)
143
+ email_output = gr.Textbox(label="Team Email", interactive=False)
144
+ predict_btn = gr.Button(f"Predict {i+1}")
145
+ inputs.append(ticket_input)
146
+ outputs.extend([team_output, email_output])
147
+ buttons.append(predict_btn)
148
+
149
+ # Action Buttons
150
+ with gr.Row():
151
+ send_btn = gr.Button("Send Tickets")
152
+ clear_btn = gr.Button("Clear")
153
+
154
+ # Output for Sent Tickets
155
+ sent_output = gr.Textbox(label="Sent Tickets", interactive=False)
156
+
157
+ # Ticket History Section
158
+ with gr.Column():
159
+ gr.Markdown("### Ticket History")
160
+ history_btn = gr.Button("View Tickets")
161
+ history_output = gr.Dataframe()
162
+
163
+ # Event Handlers for Predict Buttons
164
+ for i, btn in enumerate(buttons):
165
+ btn.click(
166
+ fn=predict_team_and_email,
167
+ inputs=inputs[i],
168
+ outputs=[outputs[i*2], outputs[i*2 + 1]]
169
+ )
170
+
171
+ # Send and Clear Handlers
172
+ send_btn.click(
173
+ fn=send_tickets,
174
+ inputs=inputs + outputs,
175
+ outputs=sent_output
176
+ )
177
+ clear_btn.click(
178
+ fn=clear_all,
179
+ inputs=None,
180
+ outputs=inputs + outputs + [sent_output]
181
+ )
182
+
183
+ # History Handler
184
+ history_btn.click(
185
+ fn=get_ticket_history,
186
+ inputs=None,
187
+ outputs=history_output
188
+ )
189
+
190
+ # Launch the interface
191
+ interface.launch()