flask-mail的小坑
阿新 • • 發佈:2021-01-11
技術標籤:pythonpythonjavavuesslmysql
<<Flask Web開發:基於Python的Web應用開發實戰>>這本書的內容,關於郵件傳送的那段程式碼已經不適用現在的情況了,修改後的極簡版程式碼如下:
#!/usr/bin/python from flask import Flask,render_template,session,redirect,url_for ,flash from flask_mail import Mail,Message from threading import Thread app = Flask(__name__) app.config['MAIL_SERVER'] = 'smtp.163.com' app.config['MAIL_PORT'] = 587 #app.config['MAIL_USE_TLS'] = True app.config['MAIL_USE_SSL'] = True app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]' app.config['FLASKY_MAIL_SENDER'] = '
[email protected]' #發件郵箱,郵箱名字和環境變數MAIL_USERNAME保持一致 app.config['FLASKY_ADMIN'] = os.environ.get('FLASKY_ADMIN') mail = Mail(app) def send_async_email(app,msg): with app.app_context(): mail.send(msg) def send_email(to,subject,template,**kwargs): msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ''+ subject, sender = app.config['FLASKY_MAIL_SENDER'],recipients=[to]) msg.body = render_template(template+'.txt', **kwargs) msg.html = render_template(template+'.html', **kwargs) #非同步傳送郵件 thr = Thread(target=send_async_email,args=[app,msg]) thr.start() return thr def index(): if app.config['FLASKY_ADMIN']: send_email(app.config['FLASKY_ADMIN'], 'New User','mail/new_user', user=user)
程式碼中三個環境變數配置:
export MAIL_USERNAME= xxx #發件郵箱名,不需要@xxx.com
export MAIL_PASSWORD=xxxxx #發件郵箱密碼(如果是163郵箱,則這裡是設定為'客戶端授權碼')
export [email protected] #收件郵箱全名,需要加上@xxx.com
不過要記住,程式要傳送大量電子郵件時,使用專門傳送電子郵件的作業要比給每封郵件都新建一個執行緒更合適。例如,可以把執行 send_async_email() 函式的操作發給 Celery 任務佇列。
注意的地方:
-
要進入郵箱確認是支援TSL還是SSL,並在程式碼做相關設定
報錯處理
報錯
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
原因:app.config['MAIL_SERVER'] = 'smtp.163.com'
寫成了app.config['MAIL_SERVER'] = 'stmp.163.com'
報錯
smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed')
原因:export MAIL_PASSWORD
填的郵箱自身密碼, 應該改為163郵箱客戶端授權碼