python flask发送邮件

python flask发送邮件
* SMTPAuthenticationError: (535, ‘Error: authentication failed’)
解决办法:调用163邮箱服务器来发送邮件,我们需要开启POP3/SMTP服务,这时163邮件会让我们设置客户端授权码,这个授权码替代上面代码部分的passwd即可成功发送邮件
安装flask-mail

pip3 install flask-mail

总体结构图

hello.py

import os
from flask import Flask, render_template, session, redirect, url_for
from flask_script import Manager, Shell
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
from flask_mail import Mail, Message

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['MAIL_SERVER'] = 'smtp.163.com'  # 163smtp服务器
app.config['MAIL_PORT'] = 25  # 端口号
app.config['MAIL_USERNAME'] = "[email protected]"
app.config['MAIL_PASSWORD'] = "abcabc"   #填写客户端授权码
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = '[email protected]'
app.config['FLASKY_ADMIN'] = "[email protected]"

manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
mail = Mail(app)


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)
    mail.send(msg)


class NameForm(Form):
    name = StringField('What is your name?', validators=[Required()])
    submit = SubmitField('Submit')


def make_shell_context():
    return dict(app=app)
manager.add_command("shell", Shell(make_context=make_shell_context))


@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 = form.name.data
        session['known'] = True
        if app.config['FLASKY_ADMIN']:
            send_email([app.config['FLASKY_ADMIN'], '[email protected]'], 'New User',
                       'mail/new_user', user=user)
        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()

404.html

{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Foundh1>
div>
{% endblock %}

500.html

{% extends "base.html" %}

{% block title %}Flasky - Internal Server Error{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Internal Server Errorh1>
div>
{% endblock %}

index.html

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!h1>
    {% if not known %}
    <p>Pleased to meet you!p>
    {% else %}
    <p>Happy to see you again!p>
    {% endif %}
div>
{{ wtf.quick_form(form) }}
{% endblock %}

base.html

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigationspan>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
            button>
            <a class="navbar-brand" href="/">Flaskya>
        div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Homea>li>
            ul>
        div>
    div>
div>
{% endblock %}

{% block content %}
<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">×button>
        {{ message }}
    div>
    {% endfor %}

    {% block page_content %}{% endblock %}
div>
{% endblock %}

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

异步发送电子邮件

from threading import Thread
def send_async_email(app,msg):
    with app.app_context():
        mail.send(msg)

def send_email(to,subject,template, **kwargs):
    msg = Message(app.config['FLASK_MAIL_SUBJECT_PREFIX']+subject,
            sender=app.config['FLASK_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

注意:很多Flask扩展都假设已经存在激活的程序上下文和请求上下文。Flask-Mail中的send()函数使用current_app,因此必须激活程序上下文。不过,在不同线程中执行mail.send()函数时,程序上下文要使用app.app_context()人工创建。

你可能感兴趣的:(python,Flask)