我们总是做着重复的事情
最近实习在cdn运维平台
上开发了几个新的模块。其中有一个功能就是邮件发送,用到了flask-mail
这个模块,想起来自己以前写邮件通知,都是重复写一样的代码,为什么不自己写个接口,curl
一下就可以发送消息了。参数通过query string
的形式提交到后端就好了。
友情提示:get
不安全,你也可以使用post
或者加一个authorization
主要代码
由于用flask-mail
太简单了,说实话我也没有开发过接口的经验,写的可能不太规范,这里只是给出一种思路,实现功能的主要代码
api server
的主要模块
# coding: utf-8
from flask import Flask, request, jsonify
from flask_mail import Mail, Message
import tasks
app = Flask(__name__)
app.config.update(
SECRET_KEY='ssoiqh234', # encrypt for cookie
MAIL_SERVER='smtp.163.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_DEFAULT_SENDER='xxx@163.com',
MAIL_USERNAME='xxx@163.com',
MAIL_PASSWORD='xxxxxx' #在网易邮件页面上授权的key
)
mail = Mail(app)
# curl http://xxx.zhxfei.com/ops/sendmail?receiver={}&title={}&text={}
@app.route('ops/sendmail', methods=['GET', 'POST'])
def new_mail():
if request.method == 'GET':
email_to_lst = request.args.get('receiver')
email_title = request.args.get('title')
email_area = request.args.get('text')
if not email_to_lst or not email_title or not email_area:
if email_to_lst:
msg = Message(subject=email_title,
body=email_area,
recipients=email_to_lst)
tasks.send_email.delay(msg, email_title, email_to_lst, email_area)
return jsonify({'success': {
'message': 'Request Send Succeed'
}}), 200
return jsonify({
'error': {
'message': 'Request Format Error'
}
}), 401
return jsonify({
'error': {
'message': 'HTTP method not allowed'
}
}), 403
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
由于mail
这种io
操作会阻塞住接口的调用,所以为了视图函数可以快速的加载,可以将其通过celery
做成异步的任务丢到任务队列中。而worker
就负责发邮件就好了。
@celery.task
def send_email(msg, *args):
with app.app_context():
mail.send(msg)
使用: curl http://xxx.zhxfei.com/ops/sendmail?receiver={}&title={}&text={}
就可以测试
由于任务是异步提交的,上面的代码是只要异步调用成功调用,就会返回一个发送成功的message
,这是不严谨的,我们可以通过celery的一些高级特性来解决问题。
比如说:
- 用
celery flower
来监控任务的运行状态,celery flower
自身也提供了接口获取当前的tasks
信息,我们可以写个脚本去遍历,当检测到failed
的tasks
,进行提醒。当然他的界面也很直观的看出。tasks
的参数(如上面的*args
会在页面中显示) - 使用
celery
的信号机制,当task_failure
信号触发,可以发送提醒通知
好了,十分钟我也只能做这些...回头验证,接口规范再完善下