Ошибка флажковой почты «SMTPServerDisconnected («сначала запустите connect()»)»

Я пишу небольшое веб-приложение на основе Flasky Мигеля Гринберга. Я использую точно такой же код для отправки пользователем почты для сброса пароля с помощью gmail.

В качестве моего файла email.py здесь я могу реализовать функцию отправки почты.

def send_password_reset_email(user):

    token = user.get_reset_password_token()
    send_email(_('[Microblog] Reset Your Password'),
               sender=current_app.config['ADMINS'][0],
               recipients=[user.email],
               text_body=render_template('email/reset_password.txt',
                                         user=user, token=token),
               html_body=render_template('email/reset_password.html',
                                         user=user, token=token))

def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)

def send_email(subject, sender, recipients, text_body, html_body):
    msg = Message(subject, sender=sender, recipients=recipients)
    msg.body = text_body
    msg.html = html_body
    Thread(target=send_async_email,
           args=(current_app._get_current_object(), msg)).start()

В файле route.py я получаю электронное письмо от пользователя, и если адрес электронной почты пользователя совпадает, я отправляю токен пользователю по почте.

@bp.route('/reset_password_request', methods=['GET', 'POST'])
def reset_password_request():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = ResetPasswordRequestForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user:
            send_password_reset_email(user)
        flash(
            _('Check your email for the instructions to reset your password'))
        return redirect(url_for('auth.login'))
    return render_template('auth/reset_password_request.html',
                           title=_('Reset Password'), form=form)


@bp.route('/reset_password/<token>', methods=['GET', 'POST'])
def reset_password(token):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    user = User.verify_reset_password_token(token)
    if not user:
        return redirect(url_for('main.index'))
    form = ResetPasswordForm()
    if form.validate_on_submit():
        user.set_password(form.password.data)
        db.session.commit()
        flash(_('Your password has been reset.'))
        return redirect(url_for('auth.login'))
    return render_template('auth/reset_password.html', form=form)

В файле model.py в модели пользователя я создаю токен для пользователя, а также проверяю токен пользователя.

def get_reset_password_token(self, expires_in=600):
        return jwt.encode(
            {'reset_password': self.id, 'exp': time() + expires_in},
            current_app.config['SECRET_KEY'],
            algorithm='HS256').decode('utf-8')
        
    @staticmethod
    def varify_reset_password_token(token):
        try:
            id = jwt.decode(token, current_app.config['SECRET_KEY'],
                            algorithms=['HS256'])['reset_password']
        except:
            return
        return User.query.get(id)

моя настройка фляжной почты выглядит следующим образом: файл config.py

    MAIL_SERVER   = os.environ.get('MAIL_SERVER')
    MAIL_PORT     = int(os.environ.get('MAIL_PORT') or 25)
    MAIL_USE_TLS  = os.environ.get('MAIL_USE_TLS') is not None
    MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    ADMINS         =['[email protected]']

Следующая ошибка, которую я получаю в терминале

Traceback (most recent call last):

  File "c:\python38\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
 
  File "c:\python38\lib\threading.py", line 870, in run     
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Ijaz Bacha\project\microblog1\app\email.py", line 9, in send_async_email
    mail.send(msg)
  File "c:\users\ijaz bacha\project\microblog1\venv\lib\site-packages\flask_mail.py", line 492, in send
    message.send(connection)
  File "c:\users\ijaz bacha\project\microblog1\venv\lib\site-packages\flask_mail.py", line 152, in __exit__
    self.host.quit()
  File "c:\python38\lib\smtplib.py", line 988, in quit      
    res = self.docmd("quit")
  File "c:\python38\lib\smtplib.py", line 424, in docmd
    self.putcmd(cmd, args)
  File "c:\python38\lib\smtplib.py", line 371, in putcmd
    self.send(str)
  File "c:\python38\lib\smtplib.py", line 363, in send
    raise SMTPServerDisconnected('please run connect() first')
smtplib.SMTPServerDisconnected: please run connect() first
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 893
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

По моему опыту, некоторое время назад у меня была очень похожая проблема, с которой вы столкнулись. После устранения неполадок я обнаружил, что мой код работает, когда я создаю почтовый класс и вызываю функцию, например $mailclass.ehlo и т. д.

Судя по ошибке, возникают проблемы с подключением или сохранением подключения. Попробуйте вызывать методы подключения в самой функции и закрывать соединение после каждого письма.

Сэр, спасибо за комментарий, можете ли вы дать мне какую-нибудь подсказку или определить для меня функцию подключения?

ijaz Bacha 10.12.2020 17:42

Я также делаю тот же учебник и столкнулся с той же проблемой. Я нашел ответ в Блоге Мигеля:

Вам нужно два окна терминала. Первый терминал, на котором запущен ваш локальный почтовый сервер, который эмулирует отправку ваших писем:

$(venv) python -m smtpd -n -c DebuggingServer localhost:8025

Главное окно терминала фляги со следующими обязательными командами (FLASK_DEBUG=1 не является обязательным, но настоятельно рекомендуется для устранения неполадок):

$ export FLASK_APP=microblog.py
$ export FLASK_DEBUG=1
$ export MAIL_SERVER=localhost
$ export MAIL_PORT=8025
$ flask run

Это решило мои проблемы.

Я решил изменить следующую строку в файле app/__init__.py:

mail = Mail(app)

с:

mail = Mail()
mail.init_app(app)

Решил проблему для меня

Другие вопросы по теме