1. 程式人生 > 其它 >flask-mail的小坑

flask-mail的小坑

技術標籤: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,並在程式碼做相關設定

    image.png

報錯處理

  • 報錯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郵箱客戶端授權碼