如何解决Flask-mail send_async_email() 生成异常和 RunTimeError:在应用程序上下文之外工作
除了 send_email() 之外,其他一切都有效。无论我使用 const matchSlugs6 = (name) => (posts) =>
map (
prop('node'),filter (
compose (any (propEq ('slug',name)),path (['node','categories'])),posts
)
)
还是远程主机,我都会遇到相同的异常。我的猜测是我没有在正确的地方推送上下文,但我已经盯着这个看了很长时间,我显然没有看到错误。任何帮助将不胜感激!
__init__.py:
localhost
views.py:
from flask import Flask,Blueprint,jsonify,...
from config import config
from flask_login import LoginManager
from extensions import db,mail,moment
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
def create_app():
app = Flask(__name__,static_url_path='',static_folder='../app/static',template_folder='../app/templates')
app.config.from_object(config['default'])
config['default'].init_app(app)
db.init_app(app)
mail.init_app(app)
moment.init_app(app)
with app.app_context():
db.create_all()
migrate = Migrate(app,db)
from app import models
from .templates.auth import auth_bp
from .templates.main import main_bp
app.register_blueprint(main_bp)
app.register_blueprint(auth_bp,url_prefix='/auth')
login_manager.init_app(app)
return app
email.py:
from flask import abort,flash,...
from flask.globals import current_app
from flask_login import current_user,login_required,login_user,logout_user
from werkzeug.security import generate_password_hash
from datetime import datetime,timezone
from wtforms.validators import UUID
from . import auth_bp
from extensions import db,common_context
from app.models. ...
from .forms import LoginForm,RegistrationForm,...
from .email import send_email
@auth_bp.route('/register/',methods=['GET','POST'],defaults={'user_id': None})
def register(user_id):
from sqlalchemy.exc import IntegrityError
from .email import send_email
if current_user.is_authenticated:
return redirect(url_for('main.home'))
form=RegistrationForm()
if form.validate_on_submit():
try:
individual = Individual(...
)
db.session.add(individual)
db.session.flush()
individual_email = Individual_email(...
)
db.session.add(individual_email)
user = User(...
)
db.session.add(user)
db.session.commit()
token = user.generate_confirmation_token()
# with current_app.app_context():
# print(individual_email.email,user,individual.first_name,token) - this works!!!
send_email(individual_email.email,'Please Confirm Your Account','auth/email/confirm',user=user,token=token,individual=individual)
flash('A confirmation email has been sent to you by email.')
except AssertionError as err:
db.session.rollback()
abort(409,err)
except IntegrityError as err:
db.session.rollback()
abort(409,err.orig)
except Exception as err:
db.session.rollback()
abort(500,err)
finally:
db.session.close()
return redirect(url_for('auth.login'))
context = {
'form': form,'title': 'Registration',}
return render_template('auth/register.html',**context,**common_context)
配置:
from flask import render_template,current_app
from flask_mail import Message
from threading import Thread
from app import mail
def send_async_email(app,msg):
with app.app_context():
mail.send(msg)
def send_email(to,subject,template,**kwargs):
app=current_app
msg = Message(app.config['MAIL_SUBJECT_PREFIX'] + subject,sender = app.config['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
输出:
import os
from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir,'.env'))
class Config(object):
DEBUG = False
TESTING = False
CSRF_ENABLED = True
SECRET_KEY = os.environ.get('SECRET_KEY')
sqlALCHEMY_TRACK_MODIFICATIONS = False
...
@staticmethod
def init_app(app):
pass
class ProductionConfig(Config):
DEBUG = False
sqlALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')
MAIL_SERVER = os.environ.get('MAIL_SERVER','smtp.gmail.com')
MAIL_PORT = int(os.environ.get('MAIL_PORT','587'))
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS','true').lower() in \
['true','on','1']
MAIL_USE_SSL = os.environ.get('MAIL_USE_SSL','false').lower()
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
MAIL_SUBJECT_PREFIX = '[...]'
MAIL_SENDER = '... <...>'
MAIL_ADMIN = os.environ.get('MAIL_ADMIN')
class DevelopmentConfig(Config):
DEVELOPMENT = True
DEBUG = True
sqlALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URI')
MAIL_SERVER = 'localhost'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
# MAIL_DEBUG = app.debug
MAIL_USERNAME = '...'
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
MAIL_DEFAULT_SENDER = '... <...>'
MAIL_MAX_EMAILS = None
# MAIL_SUPPRESS_SEND = app.testing
MAIL_ASCII_ATTACHMENTS = False
MAIL_SUBJECT_PREFIX = '[...]'
MAIL_SENDER = '... <...>'
MAIL_ADMIN = '...'
config = {
'development': DevelopmentConfig,'testing': TestingConfig,'production': ProductionConfig,'default': DevelopmentConfig
}
解决方法
将 main = [
['I','want','dog'],['driving','a','car'],['S','O','S']
]
leading = iter(['yes','no','yes'])
joined = [[next(leading),' '.join(m)] for m in main]
import csv
with open('output.csv','w') as f:
writer = csv.writer(f)
writer.writerows(joined)
中的两个函数合二为一以避免上下文问题:
email.py
第一次尝试效果很好。我查看了其他 Stackoverflow 帖子并收到了将 def send_email(to,subject,template,**kwargs):
app=current_app
with app.app_context():
msg = Message(app.config['MAIL_SUBJECT_PREFIX'] + subject,sender =
app.config['MAIL_SENDER'],recipients=[to])
msg.body = render_template(template + '.txt',**kwargs)
msg.html = render_template(template + '.html',**kwargs)
Thread(target=mail.send(msg)).start()
导入此模块的建议。我建议不要走这条路。我有两个实例,而不是一个或相同的异常,具体取决于 create_app
调用的位置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。