byinab commited on
Commit
815c4cc
Β·
verified Β·
1 Parent(s): f9c20ec

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +142 -95
src/streamlit_app.py CHANGED
@@ -1,21 +1,57 @@
1
- # Install (run once)
2
- !pip install -q transformers accelerate torch ipywidgets
3
-
4
  from transformers import pipeline
5
- from IPython.display import display, clear_output
6
- import ipywidgets as widgets
7
-
8
- print("Loading WORKING 3 PIPELINES...")
9
-
10
- # βœ… WORKING PIPELINES (your other 2 models + reliable classifier)
11
- classifier = pipeline("text-classification", model="distilbert-base-uncased")
12
- generator = pipeline("text-generation", model="Kunal7370944861/Email-Writer-AI")
13
- translator = pipeline("translation", model="DDDSSS/translation_en-zh")
14
-
15
- print("βœ… ALL PIPELINES LOADED!")
16
 
17
- # Helper functions (unchanged)
18
- def classify_email(text: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  result = classifier(text[:512])[0]
20
  return result["label"], float(result["score"])
21
 
@@ -29,90 +65,101 @@ Customer email:
29
  Write a polite, concise reply template.
30
  Reply:"""
31
 
32
- def generate_reply(prompt: str) -> str:
33
- outputs = generator(prompt, max_length=300, num_return_sequences=1, do_sample=True, temperature=0.7)
 
 
 
 
 
 
 
34
  full_text = outputs[0]["generated_text"]
35
  if "Reply:" in full_text:
36
  return full_text.split("Reply:", 1)[-1].strip()
37
  return full_text.replace(prompt, "").strip()
38
 
39
- def translate_reply(text: str) -> str:
40
- if not text.strip(): return ""
 
41
  outputs = translator(text)
42
  return outputs[0]["translation_text"].strip()
43
 
44
- # UI
45
- print("\n" + "="*70)
46
- print("πŸ“§ EMAIL PROCESSOR - READY!")
47
- print("="*70)
48
-
49
- email_input = widgets.Textarea(
50
- value="",
51
- placeholder="Paste your email here...",
52
- layout=widgets.Layout(width='98%', height='120px')
53
- )
54
-
55
- process_btn = widgets.Button(
56
- description="πŸš€ PROCESS EMAIL",
57
- button_style='success',
58
- layout=widgets.Layout(width='220px')
59
- )
60
-
61
- clear_btn = widgets.Button(
62
- description="🧹 CLEAR",
63
- button_style='warning',
64
- layout=widgets.Layout(width='120px')
65
- )
66
-
67
- output_box = widgets.Output()
68
-
69
- def on_process_clicked(b):
70
- with output_box:
71
- clear_output(wait=True)
72
- email_text = email_input.value.strip()
73
-
74
- if not email_text:
75
- print("❌ Paste an email!")
76
- return
77
-
78
- print("πŸ“§ EMAIL")
79
- print("-"*60)
80
- print(email_text)
81
- print("\n"+"="*60)
82
-
83
- # PIPELINE 1: WORKING CLASSIFIER
84
- print("πŸ”’ PIPELINE 1: distilbert-base-uncased-finetuned-sst-2-english")
85
- label, score = classify_email(email_text)
86
- print(f"βœ… TAG: **{label}** ({score:.1%})")
87
-
88
- # PIPELINE 2: YOUR MODEL
89
- print("\nβœ‰οΈ PIPELINE 2: Kunal7370944861/Email-Writer-AI")
90
- prompt = build_prompt(email_text, label)
91
- reply_en = generate_reply(prompt)
92
- print("βœ… ENGLISH REPLY:")
93
- print("-"*60)
94
- print(reply_en)
95
-
96
- # PIPELINE 3: YOUR MODEL
97
- print("\nπŸ‡¨πŸ‡³ PIPELINE 3: DDDSSS/translation_en-zh")
98
- reply_zh = translate_reply(reply_en)
99
- print("βœ… δΈ­ζ–‡ε›žε€:")
100
- print("-"*60)
101
- print(reply_zh)
102
-
103
- print("\nπŸŽ‰ DONE!")
104
-
105
- def on_clear_clicked(b):
106
- email_input.value = ""
107
- output_box.clear_output()
108
-
109
- process_btn.on_click(on_process_clicked)
110
- clear_btn.on_click(on_clear_clicked)
111
-
112
- display(widgets.VBox([
113
- widgets.HTML("<h3>πŸ“¨ Paste Email (Blank Input)</h3>"),
114
- email_input,
115
- widgets.HBox([process_btn, clear_btn]),
116
- widgets.HTML("<br>"),
117
- output_box
118
- ]))
 
 
 
 
1
+ import streamlit as st
2
+ import torch
 
3
  from transformers import pipeline
4
+ import time
5
+
6
+ # Page config
7
+ st.set_page_config(
8
+ page_title="πŸ“§ Email Reply Assistant",
9
+ page_icon="πŸ“§",
10
+ layout="wide",
11
+ initial_sidebar_state="expanded"
12
+ )
 
 
13
 
14
+ # Custom CSS
15
+ st.markdown("""
16
+ <style>
17
+ .main-header { font-size: 3rem; color: #1f77b4; text-align: center; margin-bottom: 2rem; }
18
+ .pipeline-card { background: #f8f9fa; padding: 1.5rem; border-radius: 10px; border-left: 5px solid #1f77b4; }
19
+ .status-success { color: #28a745; font-weight: bold; }
20
+ .status-loading { color: #ffc107; font-weight: bold; }
21
+ </style>
22
+ """, unsafe_allow_html=True)
23
+
24
+ @st.cache_resource
25
+ def load_pipelines():
26
+ """Load all 3 pipelines with GPU support"""
27
+ with st.spinner("Loading AI models... This takes ~2 minutes"):
28
+ classifier = pipeline(
29
+ "text-classification",
30
+ model="distilbert-base-uncased",
31
+ device=0 if torch.cuda.is_available() else -1
32
+ )
33
+ generator = pipeline(
34
+ "text-generation",
35
+ model="Kunal7370944861/Email-Writer-AI",
36
+ device=0 if torch.cuda.is_available() else -1
37
+ )
38
+ translator = pipeline(
39
+ "translation",
40
+ model="DDDSSS/translation_en-zh",
41
+ device=0 if torch.cuda.is_available() else -1
42
+ )
43
+ return classifier, generator, translator
44
+
45
+ # Load pipelines
46
+ try:
47
+ classifier, generator, translator = load_pipelines()
48
+ st.success("βœ… All 3 AI pipelines loaded!")
49
+ except Exception as e:
50
+ st.error(f"❌ Pipeline loading failed: {str(e)}")
51
+ st.stop()
52
+
53
+ # Helper functions (same logic)
54
+ def classify_email(text: str, classifier):
55
  result = classifier(text[:512])[0]
56
  return result["label"], float(result["score"])
57
 
 
65
  Write a polite, concise reply template.
66
  Reply:"""
67
 
68
+ def generate_reply(prompt: str, generator):
69
+ outputs = generator(
70
+ prompt,
71
+ max_length=300,
72
+ num_return_sequences=1,
73
+ do_sample=True,
74
+ temperature=0.7,
75
+ pad_token_id=generator.tokenizer.eos_token_id
76
+ )
77
  full_text = outputs[0]["generated_text"]
78
  if "Reply:" in full_text:
79
  return full_text.split("Reply:", 1)[-1].strip()
80
  return full_text.replace(prompt, "").strip()
81
 
82
+ def translate_reply(text: str, translator):
83
+ if not text.strip():
84
+ return ""
85
  outputs = translator(text)
86
  return outputs[0]["translation_text"].strip()
87
 
88
+ # Main title
89
+ st.markdown('<h1 class="main-header">πŸ€– Email Reply Assistant</h1>', unsafe_allow_html=True)
90
+ st.markdown("**Classify β†’ Generate Reply β†’ Translate to Chinese** β€’ Powered by 3 Transformer models")
91
+
92
+ # Sidebar info
93
+ with st.sidebar:
94
+ st.header("ℹ️ Pipeline Info")
95
+ st.markdown("""
96
+ **Pipeline 1**: `distilbert-base-uncased` β†’ Email classification
97
+ **Pipeline 2**: `Kunal7370944861/Email-Writer-AI` β†’ Reply generation
98
+ **Pipeline 3**: `DDDSSS/translation_en-zh` β†’ Chinese translation
99
+
100
+ **Status**: βœ… All models loaded
101
+ """)
102
+ st.markdown("---")
103
+ st.info("πŸ‘ˆ Paste email β†’ Click Process β†’ Get instant replies!")
104
+
105
+ # Main content
106
+ col1, col2 = st.columns([1, 2])
107
+
108
+ with col1:
109
+ st.header("πŸ“¨ Input Email")
110
+
111
+ # Email input
112
+ email_text = st.text_area(
113
+ "Paste your email here...",
114
+ placeholder="Subject: Problem with order\n\nHello,\n\nMy package arrived damaged...",
115
+ height=200,
116
+ help="Paste complete email (subject + body)"
117
+ )
118
+
119
+ col_btn1, col_btn2 = st.columns(2)
120
+ with col_btn1:
121
+ process_btn = st.button("πŸš€ PROCESS EMAIL", type="primary", use_container_width=True)
122
+ with col_btn2:
123
+ if st.button("🧹 CLEAR", use_container_width=True):
124
+ st.rerun()
125
+
126
+ with col2:
127
+ if process_btn and email_text.strip():
128
+ with st.spinner("πŸ”„ Processing through 3 AI pipelines..."):
129
+ # Pipeline 1: Classification
130
+ with st.container():
131
+ st.markdown('<div class="pipeline-card"><h3>πŸ”’ Pipeline 1: Classification</h3>', unsafe_allow_html=True)
132
+ label, score = classify_email(email_text, classifier)
133
+ col_a, col_b = st.columns(2)
134
+ col_a.metric("Recommended Tag", label)
135
+ col_b.metric("Confidence", f"{score:.1%}")
136
+ st.markdown('</div>', unsafe_allow_html=True)
137
+
138
+ # Pipeline 2: Reply Generation
139
+ with st.container():
140
+ st.markdown('<div class="pipeline-card"><h3>βœ‰οΈ Pipeline 2: English Reply</h3>', unsafe_allow_html=True)
141
+ prompt = build_prompt(email_text, label)
142
+ reply_en = generate_reply(prompt, generator)
143
+ st.text_area("English Reply Template", reply_en, height=150, disabled=True)
144
+ st.markdown('</div>', unsafe_allow_html=True)
145
+
146
+ # Pipeline 3: Translation
147
+ with st.container():
148
+ st.markdown('<div class="pipeline-card"><h3>πŸ‡¨πŸ‡³ Pipeline 3: Chinese Translation</h3>', unsafe_allow_html=True)
149
+ reply_zh = translate_reply(reply_en, translator)
150
+ st.text_area("δΈ­ζ–‡ε›žε€ζ¨‘ζΏ", reply_zh, height=150, disabled=True)
151
+ st.markdown('</div>', unsafe_allow_html=True)
152
+
153
+ # Copy buttons
154
+ st.markdown("---")
155
+ col_c, col_d = st.columns(2)
156
+ with col_c:
157
+ st.download_button("πŸ“₯ Download English", reply_en, "reply_en.txt")
158
+ with col_d:
159
+ st.download_button("πŸ“₯ Download Chinese", reply_zh, "reply_zh.txt")
160
+ else:
161
+ st.info("πŸ‘† **Paste an email and click 'PROCESS EMAIL'** to see the magic!")
162
+
163
+ # Footer
164
+ st.markdown("---")
165
+ st.markdown("*Built with ❀️ using Streamlit + Transformers β€’ Deployed on Hugging Face Spaces*")