烧瓶邮件异常
Posted
技术标签:
【中文标题】烧瓶邮件异常【英文标题】:Flask Mail Exception 【发布时间】:2015-01-11 05:16:18 【问题描述】:我签出 6b(《Flask Web 开发》一书,第 6 章邮件),我想发送一封电子邮件进行测试。但是它引发了异常。我使用虚拟机(CentOS 7)。异常如下:
(venv)➜ flasky git:(09d4ff0) ✗ python hello.py runserver --host 0.0.0.0
* Running on http://0.0.0.0:5000/
192.168.182.1 - - [10/Jan/2015 22:03:06] "GET / HTTP/1.1" 200 -
192.168.182.1 - - [10/Jan/2015 22:03:10] "POST / HTTP/1.1" 302 -
192.168.182.1 - - [10/Jan/2015 22:03:10] "GET / HTTP/1.1" 200 -
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
File "hello.py", line 63, in send_async_email
mail.send(msg)
File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 491, in send
with self.connect() as connection:
File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 144, in __enter__
self.host = self.configure_host()
File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 158, in configure_host
host = smtplib.SMTP(self.mail.server, self.mail.port)
File "/usr/lib64/python2.7/smtplib.py", line 250, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib64/python2.7/smtplib.py", line 311, in connect
(code, msg) = self.getreply()
File "/usr/lib64/python2.7/smtplib.py", line 362, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
SMTPServerDisconnected: Connection unexpectedly closed
我使用本地 IP,但我可以连接到互联网。我更改了一些配置:邮件、端口、用户名、密码。 hello.py 作为流:
import os
from threading import Thread
from flask import Flask, render_template, session, redirect, url_for
from flask.ext.script import Manager, Shell
from flask.ext.bootstrap import Bootstrap
from flask.ext.moment import Moment
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.mail import Mail, Message
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config['SQLALCHEMY_DATABASE_URI'] =\
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_TLS'] = True
#app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
#app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
app.config['MAIL_USERNAME'] = mail
app.config['MAIL_PASSWORD'] = password
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin <flasky@example.com>'
#app.config['FLASKY_ADMIN'] = os.environ.get('FLASKY_ADMIN')
app.config['FLASKY_ADMIN'] = another_mail
manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
mail = Mail(app)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
users = db.relationship('User', backref='role', lazy='dynamic')
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return '<User %r>' % self.username
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
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.name.data).first()
if user is None:
user = User(username=form.name.data)
db.session.add(user)
session['known'] = False
if app.config['FLASKY_ADMIN']:
send_email(app.config['FLASKY_ADMIN'], 'New User',
'mail/new_user', user=user)
else:
session['known'] = True
session['name'] = form.name.data
return redirect(url_for('index'))
return render_template('index.html', form=form, name=session.get('name'),
known=session.get('known', False))
if __name__ == '__main__':
manager.run()
我无法处理这个问题。
【问题讨论】:
您确定您的主机使用 TLS 吗? @BurhanKhalid 这个问题确实是由 TLS 引起的,我禁用了 MAIL_USE_SSL 选项并更改了与我使用的邮件服务器对应的端口。现在可以了。 【参考方案1】:我认为你应该使用 SSL。
app.config['MAIL_USE_SSL'] = True
您也可以尝试从配置中删除 TLS
【讨论】:
以上是关于烧瓶邮件异常的主要内容,如果未能解决你的问题,请参考以下文章