lgccccc commited on
Commit
1c03f23
·
verified ·
1 Parent(s): 0aae7c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +305 -64
app.py CHANGED
@@ -1,108 +1,349 @@
1
  import os
 
2
  import smtplib
3
  import ssl
4
- import html
5
- from email.header import Header
6
  from email.mime.multipart import MIMEMultipart
7
  from email.mime.text import MIMEText
 
8
 
9
  import gradio as gr
10
 
11
- import socket
12
 
13
- def test_smtp_dns_and_port():
14
- host = "smtpauth.intel.com"
15
- port = 587
 
 
 
16
 
 
 
 
 
 
 
 
 
17
  try:
18
- ip = socket.gethostbyname(host)
 
 
 
 
 
 
 
 
 
 
 
19
  except Exception as e:
20
- return f"DNS 解析失败:{type(e).__name__}: {e}"
 
 
 
 
 
 
 
21
 
 
 
 
 
 
 
22
  try:
23
- with socket.create_connection((host, port), timeout=10):
24
- return f"DNS 解析成功:{host} -> {ip}\n端口连接成功:{port}"
 
 
 
25
  except Exception as e:
26
- return f"DNS 解析成功:{host} -> {ip}\n但端口连接失败:{type(e).__name__}: {e}"
 
 
 
27
 
28
- SMTP_SERVER = "smtpauth.intel.com"
29
- SMTP_PORT = 587
30
 
31
- SENDER = "wenjiao.yue@intel.com"
32
- RECIPIENTS = [
33
- "wenjiao.yue@intel.com",
34
- "kaokao.lv@intel.com",
35
- ]
 
 
 
 
36
 
 
 
37
 
38
- def send_simple_email(subject: str, html_body: str):
39
- password = os.getenv("MAIL_PASSWORD")
40
 
41
- if not password:
42
- raise RuntimeError("MAIL_PASSWORD is not set in Hugging Face Space Secrets.")
 
43
 
44
- message = MIMEMultipart("alternative")
45
- message["From"] = SENDER
46
- message["To"] = ", ".join(RECIPIENTS)
47
- message["Subject"] = str(Header(subject, "utf-8"))
48
- message.attach(MIMEText(html_body, "html", "utf-8"))
49
 
50
- context = ssl.create_default_context()
51
 
52
- with smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=60) as smtp:
53
- smtp.ehlo()
54
- smtp.starttls(context=context)
55
- smtp.ehlo()
56
- smtp.login(SENDER, password)
57
- smtp.sendmail(SENDER, RECIPIENTS, message.as_string())
58
 
59
 
60
- def model_inference(user_input: str):
61
- result = f"模型推理完成,输入内容是:{user_input}"
 
 
 
 
 
 
 
 
 
 
62
 
63
- safe_input = html.escape(user_input)
64
- safe_result = html.escape(result)
65
 
66
  try:
67
- send_simple_email(
68
- subject="Hugging Face Space 模型推理完成通知",
69
- html_body=f"""
70
- <h3>模型推理已完成</h3>
71
- <p><b>输入内容</b>{safe_input}</p>
72
- <p><b>推理结果:</b>{safe_result}</p>
73
- <p>请回到 Hugging Face Space 页面查看完整结果。</p>
74
- """,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  )
76
- email_status = "邮件通知已发送"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  except Exception as e:
78
- email_status = f"邮件通知发送失败:{type(e).__name__}: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- return f"{result}\n\n{email_status}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
 
83
  with gr.Blocks() as demo:
84
- gr.Markdown("# 模型推理完成后自动邮件通知")
85
 
86
- user_input = gr.Textbox(label="输入")
87
- output = gr.Textbox(label="结果")
 
88
 
89
- btn = gr.Button("开始推理")
 
 
 
 
 
90
 
91
- btn.click(
92
- fn=model_inference,
93
- inputs=user_input,
94
- outputs=output,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  )
96
 
 
97
 
98
- test_btn = gr.Button("测试 SMTP 连接")
99
- test_output = gr.Textbox(label="SMTP 测试结果")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- test_btn.click(
102
- fn=test_smtp_dns_and_port,
103
- inputs=None,
104
- outputs=test_output,
105
- )
106
 
107
  demo.queue()
108
  demo.launch()
 
1
  import os
2
+ import socket
3
  import smtplib
4
  import ssl
5
+ import traceback
 
6
  from email.mime.multipart import MIMEMultipart
7
  from email.mime.text import MIMEText
8
+ from email.header import Header
9
 
10
  import gradio as gr
11
 
 
12
 
13
+ # 建议在 Hugging Face Space Settings -> Variables / Secrets 中配置
14
+ DEFAULT_SMTP_SERVER = os.getenv("SMTP_SERVER", "smtpauth.intel.com")
15
+ DEFAULT_SMTP_PORT = int(os.getenv("SMTP_PORT", "587"))
16
+
17
+ DEFAULT_MAIL_SENDER = os.getenv("MAIL_SENDER", "wenjiao.yue@intel.com")
18
+ DEFAULT_MAIL_TO = os.getenv("MAIL_TO", "wenjiao.yue@intel.com")
19
 
20
+ MAIL_PASSWORD = os.getenv("MAIL_PASSWORD")
21
+
22
+
23
+ def test_dns(smtp_server: str, smtp_port: int):
24
+ """
25
+ 测试 DNS 解析。
26
+ 如果这里失败,说明还没到端口连接阶段。
27
+ """
28
  try:
29
+ results = socket.getaddrinfo(smtp_server, smtp_port)
30
+ formatted = []
31
+
32
+ for item in results:
33
+ family, socktype, proto, canonname, sockaddr = item
34
+ formatted.append(
35
+ f"family={family}, socktype={socktype}, proto={proto}, "
36
+ f"canonname={canonname}, sockaddr={sockaddr}"
37
+ )
38
+
39
+ return True, "DNS 解析成功:\n" + "\n".join(formatted)
40
+
41
  except Exception as e:
42
+ return False, (
43
+ f"DNS 解析失败:{repr(e)}\n\n"
44
+ f"SMTP_SERVER={smtp_server}\n"
45
+ f"SMTP_PORT={smtp_port}\n\n"
46
+ "说明 Hugging Face Space 当前无法把这个域名解析成 IP。\n"
47
+ "这通常不是端口问题,而是域名在公网 DNS 中不可解析,"
48
+ "或者它依赖公司内网 DNS。"
49
+ )
50
 
51
+
52
+ def test_tcp_connection(smtp_server: str, smtp_port: int):
53
+ """
54
+ 测试 TCP 连接。
55
+ DNS 成功后,才会测试到这一步。
56
+ """
57
  try:
58
+ with socket.create_connection((smtp_server, smtp_port), timeout=15) as sock:
59
+ peer = sock.getpeername()
60
+
61
+ return True, f"TCP 连接成功:{smtp_server}:{smtp_port}, peer={peer}"
62
+
63
  except Exception as e:
64
+ return False, (
65
+ f"TCP 连接失败:{repr(e)}\n\n"
66
+ "如果 DNS 成功但这里失败,才可能是端口、防火墙、网络策略问题。"
67
+ )
68
 
 
 
69
 
70
+ def test_smtp_handshake(smtp_server: str, smtp_port: int):
71
+ """
72
+ 测试 SMTP EHLO 和 STARTTLS。
73
+ """
74
+ logs = []
75
+
76
+ try:
77
+ with smtplib.SMTP(smtp_server, smtp_port, timeout=30) as smtp:
78
+ smtp.set_debuglevel(0)
79
 
80
+ code, msg = smtp.ehlo()
81
+ logs.append(f"EHLO 返回:code={code}, msg={msg!r}")
82
 
83
+ if code != 250:
84
+ return False, "\n".join(logs) + "\n\nEHLO 失败。"
85
 
86
+ context = ssl._create_unverified_context()
87
+ code, msg = smtp.starttls(context=context)
88
+ logs.append(f"STARTTLS 返回:code={code}, msg={msg!r}")
89
 
90
+ code, msg = smtp.ehlo()
91
+ logs.append(f"TLS 后 EHLO 返回:code={code}, msg={msg!r}")
 
 
 
92
 
93
+ return True, "SMTP 握手成功:\n" + "\n".join(logs)
94
 
95
+ except Exception as e:
96
+ logs.append(f"SMTP 握手失败:{repr(e)}")
97
+ logs.append(traceback.format_exc())
98
+ return False, "\n".join(logs)
 
 
99
 
100
 
101
+ def test_smtp_login(smtp_server: str, smtp_port: int, mail_sender: str):
102
+ """
103
+ 测试 SMTP 登录。
104
+ 需要 MAIL_PASSWORD 在 HF Space Secrets 中配置。
105
+ """
106
+ if not MAIL_PASSWORD:
107
+ return False, (
108
+ "MAIL_PASSWORD 未设置。\n\n"
109
+ "请在 Hugging Face Space 里配置:\n"
110
+ "Settings -> Variables and secrets -> New secret\n\n"
111
+ "MAIL_PASSWORD=你的邮箱密码或授权码"
112
+ )
113
 
114
+ logs = []
 
115
 
116
  try:
117
+ context = ssl._create_unverified_context()
118
+
119
+ with smtplib.SMTP(smtp_server, smtp_port, timeout=30) as smtp:
120
+ code, msg = smtp.ehlo()
121
+ logs.append(f"EHLO 返回code={code}, msg={msg!r}")
122
+
123
+ code, msg = smtp.starttls(context=context)
124
+ logs.append(f"STARTTLS 返回:code={code}, msg={msg!r}")
125
+
126
+ code, msg = smtp.ehlo()
127
+ logs.append(f"TLS 后 EHLO 返回:code={code}, msg={msg!r}")
128
+
129
+ smtp.login(mail_sender, MAIL_PASSWORD)
130
+ logs.append("SMTP 登录成功。")
131
+
132
+ return True, "\n".join(logs)
133
+
134
+ except Exception as e:
135
+ logs.append(f"SMTP 登录失败:{repr(e)}")
136
+ logs.append(traceback.format_exc())
137
+ return False, "\n".join(logs)
138
+
139
+
140
+ def send_test_email(
141
+ smtp_server: str,
142
+ smtp_port: int,
143
+ mail_sender: str,
144
+ mail_to: str,
145
+ ):
146
+ """
147
+ 真实发送测试邮件。
148
+ """
149
+ if not MAIL_PASSWORD:
150
+ return False, (
151
+ "MAIL_PASSWORD 未设置,无法发送邮件。\n\n"
152
+ "请在 Hugging Face Space Secrets 中设置 MAIL_PASSWORD。"
153
  )
154
+
155
+ subject = "Hugging Face Space SMTP Test"
156
+ html_body = f"""
157
+ <h3>Hugging Face Space SMTP Test</h3>
158
+ <p>这是一封来自 Hugging Face Space 的 SMTP 测试邮件。</p>
159
+ <p><b>SMTP Server:</b> {smtp_server}</p>
160
+ <p><b>SMTP Port:</b> {smtp_port}</p>
161
+ <p><b>Sender:</b> {mail_sender}</p>
162
+ <p><b>Recipient:</b> {mail_to}</p>
163
+ """
164
+
165
+ msg = MIMEMultipart("alternative")
166
+ msg["From"] = Header(mail_sender)
167
+ msg["To"] = Header(mail_to)
168
+ msg["Subject"] = Header(subject, "utf-8")
169
+ msg.attach(MIMEText(html_body, "html", "utf-8"))
170
+
171
+ logs = []
172
+
173
+ try:
174
+ context = ssl._create_unverified_context()
175
+
176
+ with smtplib.SMTP(smtp_server, smtp_port, timeout=60) as smtp:
177
+ code, message = smtp.ehlo()
178
+ logs.append(f"EHLO 返回:code={code}, msg={message!r}")
179
+
180
+ code, message = smtp.starttls(context=context)
181
+ logs.append(f"STARTTLS 返回:code={code}, msg={message!r}")
182
+
183
+ code, message = smtp.ehlo()
184
+ logs.append(f"TLS 后 EHLO 返回:code={code}, msg={message!r}")
185
+
186
+ smtp.login(mail_sender, MAIL_PASSWORD)
187
+ logs.append("SMTP 登录成功。")
188
+
189
+ smtp.sendmail(mail_sender, [mail_to], msg.as_string())
190
+ logs.append(f"测试邮件发送成功:{mail_sender} -> {mail_to}")
191
+
192
+ return True, "\n".join(logs)
193
+
194
  except Exception as e:
195
+ logs.append(f"测试邮件发送失败:{repr(e)}")
196
+ logs.append(traceback.format_exc())
197
+ return False, "\n".join(logs)
198
+
199
+
200
+ def run_all_tests(
201
+ smtp_server: str,
202
+ smtp_port: int,
203
+ mail_sender: str,
204
+ mail_to: str,
205
+ actually_send_email: bool,
206
+ ):
207
+ """
208
+ 按顺序执行所有测试。
209
+ """
210
+ smtp_server = smtp_server.strip()
211
+ smtp_port = int(smtp_port)
212
+ mail_sender = mail_sender.strip()
213
+ mail_to = mail_to.strip()
214
+
215
+ final_logs = []
216
 
217
+ final_logs.append("========== 配置 ==========")
218
+ final_logs.append(f"SMTP_SERVER={smtp_server}")
219
+ final_logs.append(f"SMTP_PORT={smtp_port}")
220
+ final_logs.append(f"MAIL_SENDER={mail_sender}")
221
+ final_logs.append(f"MAIL_TO={mail_to}")
222
+ final_logs.append(f"MAIL_PASSWORD_SET={bool(MAIL_PASSWORD)}")
223
+ final_logs.append("")
224
+
225
+ final_logs.append("========== 1. DNS 测试 ==========")
226
+ ok, log = test_dns(smtp_server, smtp_port)
227
+ final_logs.append(log)
228
+ final_logs.append("")
229
+
230
+ if not ok:
231
+ final_logs.append("结论:DNS 解析失败。")
232
+ final_logs.append("这不是端口问题,因为程序还没有进入连接端口阶段。")
233
+ return "\n".join(final_logs)
234
+
235
+ final_logs.append("========== 2. TCP 连接测试 ==========")
236
+ ok, log = test_tcp_connection(smtp_server, smtp_port)
237
+ final_logs.append(log)
238
+ final_logs.append("")
239
+
240
+ if not ok:
241
+ final_logs.append("结论:DNS 成功,但 TCP 连接失败。")
242
+ final_logs.append("这可能是端口、防火墙、网络策略或 SMTP 服务不允许外部访问。")
243
+ return "\n".join(final_logs)
244
+
245
+ final_logs.append("========== 3. SMTP EHLO / STARTTLS 测试 ==========")
246
+ ok, log = test_smtp_handshake(smtp_server, smtp_port)
247
+ final_logs.append(log)
248
+ final_logs.append("")
249
+
250
+ if not ok:
251
+ final_logs.append("结论:TCP 连接成功,但 SMTP 握手或 STARTTLS 失败。")
252
+ return "\n".join(final_logs)
253
+
254
+ final_logs.append("========== 4. SMTP 登录测试 ==========")
255
+ ok, log = test_smtp_login(smtp_server, smtp_port, mail_sender)
256
+ final_logs.append(log)
257
+ final_logs.append("")
258
+
259
+ if not ok:
260
+ final_logs.append("结论:SMTP 服务可访问,但登录失败。")
261
+ final_logs.append("请检查 MAIL_SENDER 和 MAIL_PASSWORD。")
262
+ return "\n".join(final_logs)
263
+
264
+ if actually_send_email:
265
+ final_logs.append("========== 5. 发送测试邮件 ==========")
266
+ ok, log = send_test_email(
267
+ smtp_server=smtp_server,
268
+ smtp_port=smtp_port,
269
+ mail_sender=mail_sender,
270
+ mail_to=mail_to,
271
+ )
272
+ final_logs.append(log)
273
+ final_logs.append("")
274
+
275
+ if ok:
276
+ final_logs.append("最终结论:SMTP 全流程成功,邮件已发送。")
277
+ else:
278
+ final_logs.append("最终结论:登录成功,但发送邮件失败。")
279
+ else:
280
+ final_logs.append("========== 5. 发送测试邮件 ==========")
281
+ final_logs.append("已跳过真实发信。勾选 `Actually send test email` 后才会发送。")
282
+ final_logs.append("")
283
+ final_logs.append("最终结论:DNS、TCP、STARTTLS、登录测试均通过。")
284
+
285
+ return "\n".join(final_logs)
286
 
287
 
288
  with gr.Blocks() as demo:
289
+ gr.Markdown("# Hugging Face Space SMTP 诊断工具")
290
 
291
+ gr.Markdown(
292
+ """
293
+ 这个页面用于测试 Hugging Face Space 是否能访问你的 SMTP 服务器。
294
 
295
+ 重点判断:
296
+ - 如果 DNS 失败:不是端口问题。
297
+ - 如果 DNS 成功但 TCP 失败:可能是端口、防火墙或网络策略问题。
298
+ - 如果 TCP 成功但登录失败:可能是用户名、密码或权限问题。
299
+ """
300
+ )
301
 
302
+ with gr.Row():
303
+ smtp_server_input = gr.Textbox(
304
+ label="SMTP_SERVER",
305
+ value=DEFAULT_SMTP_SERVER,
306
+ )
307
+ smtp_port_input = gr.Number(
308
+ label="SMTP_PORT",
309
+ value=DEFAULT_SMTP_PORT,
310
+ precision=0,
311
+ )
312
+
313
+ with gr.Row():
314
+ mail_sender_input = gr.Textbox(
315
+ label="MAIL_SENDER",
316
+ value=DEFAULT_MAIL_SENDER,
317
+ )
318
+ mail_to_input = gr.Textbox(
319
+ label="MAIL_TO",
320
+ value=DEFAULT_MAIL_TO,
321
+ )
322
+
323
+ actually_send_email = gr.Checkbox(
324
+ label="Actually send test email",
325
+ value=False,
326
  )
327
 
328
+ run_button = gr.Button("Run SMTP Tests")
329
 
330
+ output = gr.Textbox(
331
+ label="测试结果",
332
+ lines=30,
333
+ )
334
+
335
+ run_button.click(
336
+ fn=run_all_tests,
337
+ inputs=[
338
+ smtp_server_input,
339
+ smtp_port_input,
340
+ mail_sender_input,
341
+ mail_to_input,
342
+ actually_send_email,
343
+ ],
344
+ outputs=output,
345
+ )
346
 
 
 
 
 
 
347
 
348
  demo.queue()
349
  demo.launch()