Я использую библиотеку Flask -Mail для моего приложения Flask, чтобы отправлять пользователю приветственное письмо по умолчанию, когда он подписывается на добавление в информационный бюллетень. После отладки библиотеки я обнаружил, что она может обрабатывать только одно соединение за раз для отправки сообщения, а затем автоматически закрывает соединение. Если серверная часть отправляет электронное письмо другому пользователю, пока соединение все еще открыто, он генерирует это исключение: raise SMTPServerDisconnected("Connection unexpectedly closed: " smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [WinError 10054] An existing connection was forcibly closed by the remote host
. Я хочу иметь возможность поставить в очередь почтовую библиотеку Mail для отправки нового сообщения другому получателю после закрытия соединения, но в настоящее время он продолжает выдавать ошибку, о которой я упоминал выше, когда я пытаюсь поставить функцию в очередь для отправки сообщения.
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()
user.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)
main.routes.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
run.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