gpt4 book ai didi

python - Flask-Mail 队列消息被发送到不同的电子邮件

转载 作者:行者123 更新时间:2023-12-03 14:37:46 32 4
gpt4 key购买 nike

我正在为我的 Flask 应用程序使用 Flask-Mail 库,以便在用户注册以添加到时事通讯时向他们发送默认的欢迎电子邮件。调试该库后,我发现它一次只能处理一个连接发送消息,然后会自动关闭连接。如果后端在连接仍处于打开状态时向另一个用户发送电子邮件,则会引发此异常:raise SMTPServerDisconnected("Connection unexpectedly closed: " smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [WinError 10054] An existing connection was forcibly closed by the remote host .我希望能够在连接关闭后将邮件库排队以向另一个收件人发送新消息,但目前当我尝试将函数排队以发送消息时,它一直抛出我上面提到的错误。
worker .py:

import os
import redis
from rq import Worker, Queue, Connection

listen = ['high', 'default', 'low']

redis_url = os.environ.get('REDISTOGO_URL')

conn = redis.from_url(redis_url)

if __name__ == '__main__':
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()
用户.routes.py
from flask import request, Blueprint, redirect, render_template
from flask_app import mail, db
from flask_app.users.forms import NewsLetterRegistrationForm
from flask_app.models import User
from flask_mail import Message
from rq import Queue
from worker import conn
import os, time

users = Blueprint("users", __name__)
queue = Queue(connection=conn)

@users.route("/newsletter-subscribe", methods=["GET", "POST"])
def newsletter_subscribe():
form = NewsLetterRegistrationForm()
if form.validate_on_submit():
user = User(name=form.name.data, email=form.email.data)
db.session.add(user)
db.session.commit()
queue.enqueue(send_welcome_email(user))

return "Success"
return "Failure"

def send_welcome_email(user):
with mail.connect() as con:
html = render_template("welcome-email.html", name=user.name)
subject = "Welcome!"
msg = Message(
subject=subject,
recipients=[user.email],
html=html
)
con.send(msg)
主路由.py
from flask import render_template, session, request, current_app, Blueprint, redirect, url_for, json, make_response
from flask_app.users.forms import NewsLetterRegistrationForm
import os

main = Blueprint("main", __name__)

@main.route("/", methods=["GET"])
def index():
return render_template("index.html", title="Home")

@main.route("/example", methods=["GET"])
def example():
return render_template("example.html", title="example")

@main.context_processor
def inject_template_scope():
injections = dict()
form = NewsLetterRegistrationForm()
injections.update(form=form)
return injections
_init_.py
from logging.config import dictConfig
from flask import Flask, url_for, current_app
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
from flask_talisman import Talisman
from flask_compress import Compress
from flask_mail import Mail
import os

config = {
"SECRET_KEY": os.environ.get("SECRET_KEY"),
"DEBUG": True,
"SQLALCHEMY_DATABASE_URI": os.environ.get("DATABASE_URL"),
"SQLALCHEMY_TRACK_MODIFICATIONS": False,
"SQLALCHEMY_ECHO": False,
"MAIL_SERVER": "mail.privateemail.com",
"MAIL_PORT": 587,
"MAIL_USE_SSL": False,
"MAIL_USE_TLS": True,
"MAIL_USERNAME": "test@example.com",
"MAIL_PASSWORD": os.environ.get("NEWS_MAIL_PASSWORD"),
"MAIL_DEFAULT_SENDER": "test@example.com"
}

talisman = Talisman()
db = SQLAlchemy()
bcrypt = Bcrypt()
compress = Compress()
mail = Mail()
app = Flask(__name__)

def create_app():
app.config.from_mapping(config)
talisman.init_app(app)
db.init_app(app)
bcrypt.init_app(app)
compress.init_app(app)
mail.init_app(app)

from flask_app.users.routes import users
app.register_blueprint(users)

with app.app_context():
db.create_all()
return app
运行.py
from flask_app import create_app
错误日志:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\smtplib.py", line 391, in getreply
line = self.file.readline(_MAXLINE + 1)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\socket.py", line 669, in readinto
return self._sock.recv_into(b)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\User\Work Stuff\example.com\flask_app\users\routes.py", line 18, in newsletter_subscribe
send_welcome_email(user, request.host_url)
File "C:\User\Work Stuff\example.com\flask_app\users\routes.py", line 42, in send_welcome_email
with mail.connect() as con:
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_mail.py",
line 144, in __enter__
self.host = self.configure_host()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_mail.py",
line 158, in configure_host
host = smtplib.SMTP(self.mail.server, self.mail.port)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\smtplib.py", line 253, in __init__
(code, msg) = self.connect(host, port)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\smtplib.py", line 341, in connect
(code, msg) = self.getreply()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\smtplib.py", line 394, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed: "
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [WinError 10054] An existing connection was forcibly closed by the remote host

最佳答案

在我看来,您的邮件服务器正在关闭连接,因为您发出的请求超出了其配置允许的数量。如果您使用的是第三方邮件提供商,您可能需要检查您使用的服务是否提供任何方式来发送批量电子邮件,例如通过 API 或文件上传。或者,如果他们有办法为您更改该配置。
如果不可能:
一种解决方案是进行阻塞调用(time.sleep()),以降低发送邮件的频率:

import time

def send_welcome_email(user):
with mail.connect() as con:
html = render_template("welcome-email.html", name=user.name)
subject = "Welcome!"
msg = Message(
subject=subject,
recipients=[user.email],
html=html
)
time.sleep(2) # 2 seconds, modify as you see fit
con.send(msg)
另一种解决方案是将您的代码包装在 try catch block 中,并在出现异常时等待一段时间,然后再尝试再次发送电子邮件。
def send_welcome_email(user, is_retry=False):
try:
with mail.connect() as con:
html = render_template("welcome-email.html", name=user.name)
subject = "Welcome!"
msg = Message(
subject=subject,
recipients=[user.email],
html=html
)
con.send(msg)
except SMTPServerDisconnected:
time.sleep(60) # Wait for a while, 1 minute tends to be a good measure as most configurations specify how many requests can be made a minute.
if not is_retry: # Only retry once -> you could modify this to make the use of a counter.
send_welcome_email(user, is_retry=True) # Try again

关于python - Flask-Mail 队列消息被发送到不同的电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63235625/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com