赵走x博客
网站访问量:151482
首页
书籍
软件
工具
古诗词
搜索
登录
Flask 实战:41、电子邮件进阶实践
Flask 实战:40、使用事务邮件服务SendGird
Flask 实战:39、使用Flask-Mail发送电子邮件
Flask 实战:38、数据库进阶实践
Flask 实战:37、更新数据库表
Flask 实战:36、定义关系
Flask 实战:35、在视图函数里操作数据库
Flask 实战:34、数据库操作:CRUD
Flask 实战:33、使用Flask-SQLAlchemy管理数据库
Flask 实战:32、ORM魔法
Flask 实战:31、数据库的分类
Flask 实战:30、单个页面多个表单
Flask 实战:29、单个表单多个提交按钮
Flask 实战:28、使用Flask-CKEditor集成富文本编辑器
Flask 实战:27、多文件上传
Flask 实战:26、文件上传
Flask 实战:25、自定义验证器
Flask 实战:24、使用宏渲染表单
Flask 实战:23、设置错误消息语言
Flask 实战:22、处理表单数据
Flask 实战:21、使用Flask-WTF处理表单
Flask 实战:20、HTML表单
Flask 实战:19、模板进阶实践
Flask 实战:18、模板结构组织
Flask 实战:17、模板辅助工具
Flask 实战:16、模板基本用法
Flask 实战:15、HTTP进阶实践
Flask 实战:14、Flask上下文
Flask 实战:13、HTTP响应
Flask 实战:12、HTTP请求
Flask 实战:11、请求响应循环
Flask 实战:10、Flask与MVC架构
Flask 实战:9、模板与静态文件
Flask 实战:8、Flask命令
Flask 实战:7、URL与端点
Flask 实战:6、项目配置
Flask 实战:5、Flask扩展
Flask 实战:4、Python Shell
Flask 实战:3、启动开发服务器
Flask 实战:2、Hello,Flask!
Flask 实战:1、初识Flask
Flask 实战:40、使用事务邮件服务SendGird
资源编号:75891
Python Web
Flask Web开发实战:入门、进阶与原理解析
热度:124
发邮件喽
在生产环境下,除了自己安装运行邮件服务器外,更方便的做法是使用事务邮件服务(Transactional Email Service),比如Mailgun([https://www.mailgun.com/](https://www.mailgun.com/) )、Sendgrid([https://sendgrid.com/](https://sendgrid.com/) )等。这两个邮件服务对免费账户分别提供每月1万封和3000封的免费额度,完全足够测试使用或在小型程序中使用。Mailgun在注册免费账户时需要填写信用卡,而Sendgrid没有这一限制,所以这一节我们将介绍使用SendGrid来发送电子邮件。 # 1、注册SendGird 我们首先需要登录SendGrid的网站注册一个免费账户,访问[https://app.sendgrid.com/signup](https://app.sendgrid.com/signup) ,填写必要的信息并验证电子邮箱即可完成注册。 注册完成后,我们需要为当前的项目创建一个API密钥,用于在程序中发送邮件时进行认证。登录控制台页面后,通过单击左侧的Settings→API Keys,然后单击右上角的“Create API Key”创建API。填写API密钥的名称(比如你的项目名称),选择权限(默认即可),然后单击“Create&View”按钮,如图所示。  创建成功后会在页面上看到密钥值,如图中的方框标识所示。  复制这个密钥,然后保存到.env文件中,我们待会会使用它来作为发信账户的密码: ``` SENDGRID_API_KEY=your_key_here ``` >注意 API密钥被创建后仅显示一次,一旦关闭了显示界面,将无法再次查看。API密钥列表中的“API key ID”并非API密钥,不能用于认证。 # 2、SendGrid SMTP转发 创建好API密钥后,我们就可以通过SendGrid提供的SMTP服务器发送电子邮件了。这种方式不需要对程序做大幅度的改动,我们唯一要做的就是修改Flask-Mail的配置,如下所示: ``` MAIL_SERVER = 'smtp.sendgrid.net' MAIL_PORT = 587 MAIL_USE_TLS = True MAIL_USERNAME = 'apikey' MAIL_PASSWORD = os.getenv('SENDGRID_API_KEY') # 从环境变量读取API密钥 ``` 在实际代码中,这几个配置变量均设置为从环境变量读取,所以你可以在.env文件中设置这几个变量值。 >提示 使用SendGrid发信时,发信人的邮件地址可以自己指定,通常会设为noreply@example.com或bot@example.com。 # 3、SendGrid Web API转发 除了提供SMTP转发,SendGrid还支持通过它提供的Web API转发邮件。和使用SMTP服务器发送邮件相比,使用Web API发送邮件更安全,而且省去了建立SMTP连接的繁琐过程,因此速度更快,尤其是需要发送大批量邮件的情况下。尽管如此,如果你想让程序更容易迁移,更关注灵活性,那么也可以选择使用更通用的SMTP,这时当需要更换邮件服务时只需要替换配置信息即可。 关于Web API,后面我们会详细了解。在这里你可以把它简单理解为SendGrid开放的一系列数据接口。 当使用SendGrid Web API发送邮件时,我们只需要像其他用户访问我们程序的URL来使用程序一样,在程序中向SendGrid提供的Web API发出一个POST请求,并附带必要的信息,比如密钥、邮件主题、收件人、正文等,SendGrid就会为我们发送邮件。 下面是一个发送邮件的POST请求报文示例,在这个示例中,我们对发送邮件的端口URL([https://api.sendgrid.com/v3/mail/send](https://api.sendgrid.com/v3/mail/send) )发送POST请求,在Authorization首部字段中提供相应的API密钥,请求报文主体是用JSON格式表示的电子邮件数据: ``` POST https://api.sendgrid.com/v3/mail/send 'Authorization: Bearer YOUR_API_KEY' 'Content-Type: application/json' '{"personalizations": [{"to": [{"email": "zorn@example.com"}]}],"from": {"email": "noreply@helloflask.com"},"subject": "Hello, World!","content": [{"type": "text/plain", "value": " Across the Great Wall we can reach every corner in the world."}]}' ``` > 附注 用于发信的API端口说明可以访问[https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html) 查看。 在命令行中使用curl一类的工具,或是使用任一个用于请求的Python库即可发送电子邮件,比如requests([http://python-requests.org/](http://python-requests.org/) )。为了更方便地在Python中构建邮件内容和发送邮件,我们可以使用SendGrid提供的官方Python SDK(Software Development Kit,软件开发工具包)——SendGrid-Python,首先使用Pipenv安装这个接口库: ``` $ pipenv install sendgrid ``` ### 1.创建发信对象 下面我们继续在Python Shell中演示发信过程。我们首先需要实例化SendGridAPIClient类创建一个发信客户端对象: ``` >>> from sendgrid import SendGridAPIClient >>> sg = SendGridAPIClient(apikey=os.getenv('SENDGRID_API_KEY')) ``` 实例化时需要使用apikey关键字传入我们在前面创建的API密钥。 ### 2.构建邮件数据 在发送发信请求前,我们需要先构建邮件数据。我们可以使用SendGrid-Python提供的一系列辅助函数来构建邮件数据: ``` >>> from sendgrid.helpers.mail import Email, Content, Mail >>> from_email = Email('noreply@helloflask.com') >>> to_email = Email('zorn@example.com') >>> subject = 'Hello, World!' >>> content = Content('text/plain', ' Across the Great Wall we can reach every corner in the world.') >>> mail = Mail(from_email, subject, to_email, content) ``` 在上面的代码中,我们首先从sendgrid.helpers.mail模块导入了三个辅助类:Email、Content和Mail。Email用来创建邮件地址,即发信地址和收信地址。Email类的构造方法依次接收email和name参数,传入值可以为三种形式:分别传入Email地址、姓名;仅传入邮箱地址;传入标准收件人字符串,即“姓名
”。 Content类的构造函数接收MIME类型(type_)和正文(value)作为参数。 Mail类则用来创建邮件对象,其构造方法接收的参数分别为发信人(from_email)、主题(subject)、收信人(to_email)和邮件正文(content)。对最终获得的mail对象调用get()方法或是直接打印会看到最终生成的表示一封邮件的预JSON值: ``` >>> mail.get() { "personalizations": [ { "to": [ { "email": "zorn@example.com" } ], "subject": "Hello, World!" }, ], "from": { "email": "noreply@helloflask.com" }, "content": [ { "type": "text/html", "value": "Across the Great Wall we can reach every corner in the world." } ], } ``` 如果不使用辅助类,你也可以手动构建这个表示邮件数据的字典。 除了这几个基础字段,SendGrid-Python还提供了其他辅助类来定义邮件首部的其他字段,具体可以参考SendGrid-Python文档或源码。 ### 3.发送邮件 通过对表示邮件客户端的sg对象调用sg.client.mail.send.post()方法,并将表示数据的字典使用关键字request_body传入即可发送发信的POST请求: ``` >>> sg.client.mail.send.post(request_body=mail.get()) ``` 发信的方法会返回响应,我们可以查看响应的内容: ``` >>> response = sg.client.mail.send.post(request_body=mail.get()) >>> print(response.status_code) >>> print(response.body) >>> print(response.headers) ``` 这部分代码即可生成我们在本节开始介绍的POST请求报文。完整的发送示例邮件的代码如下所示: ``` import sendgrid import os from sendgrid.helpers.mail import * sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) from_email = Email('noreply@helloflask.com') to_email = Email('zorn@example.com') subject = 'Hello, World!' content = Content('text/plain', ' Across the Great Wall we can reach every corner in the world.') mail = Mail(from_email, subject, to_email, content) response = sg.client.mail.send.post(request_body=mail.get()) print(response.status_code) print(response.body) print(response.headers) ``` 我们可以像使用Flask-Mail一样创建一个通用的发信函数,用来在视图函数里调用,如代码清单所示。 ``` import sendgrid import os from sendgrid.helpers.mail import * def send_email(subject, to, body): sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) from_email = Email('noreply@helloflask.com') to_email = Email(to) content = Content("text/plain", body) mail = Mail(from_email, subject, to_email, content) response = sg.client.mail.send.post(request_body=mail.get()) ``` > 附注 在SendGrid的Web程序上([https://app.sendgrid.com/email_activity](https://app.sendgrid.com/email_activity) ),你可以监控每一封邮件的送达状态和被阅读状态等。除了常规的邮件转发功能,像SendGrid这类事务邮件服务通常还会提供邮件模板、联系人管理、订阅和退订管理等功能,更多的用法请访问SendGrid官方文档([https://sendgrid.com/docs/index.html](https://sendgrid.com/docs/index.html) )了解。