我們總是做著重復(fù)的事情
最近實(shí)習(xí)在cdn運(yùn)維平臺(tái)
上開發(fā)了幾個(gè)新的模塊。其中有一個(gè)功能就是郵件發(fā)送,用到了flask-mail
這個(gè)模塊,想起來自己以前寫郵件通知,都是重復(fù)寫一樣的代碼,為什么不自己寫個(gè)接口,curl
一下就可以發(fā)送消息了。參數(shù)通過query string
的形式提交到后端就好了。
友情提示:get
不安全,你也可以使用post
或者加一個(gè)authorization
主要代碼
由于用flask-mail
太簡(jiǎn)單了,說實(shí)話我也沒有開發(fā)過接口的經(jīng)驗(yàn),寫的可能不太規(guī)范,這里只是給出一種思路,實(shí)現(xiàn)功能的主要代碼
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' #在網(wǎng)易郵件頁面上授權(quán)的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
操作會(huì)阻塞住接口的調(diào)用,所以為了視圖函數(shù)可以快速的加載,可以將其通過celery
做成異步的任務(wù)丟到任務(wù)隊(duì)列中。而worker
就負(fù)責(zé)發(fā)郵件就好了。
@celery.task
def send_email(msg, *args):
with app.app_context():
mail.send(msg)
使用: curl http://xxx.zhxfei.com/ops/sendmail?receiver={}&title={}&text={}
就可以測(cè)試
由于任務(wù)是異步提交的,上面的代碼是只要異步調(diào)用成功調(diào)用,就會(huì)返回一個(gè)發(fā)送成功的message
,這是不嚴(yán)謹(jǐn)?shù)模覀兛梢酝ㄟ^celery的一些高級(jí)特性來解決問題。
比如說:
- 用
celery flower
來監(jiān)控任務(wù)的運(yùn)行狀態(tài),celery flower
自身也提供了接口獲取當(dāng)前的tasks
信息,我們可以寫個(gè)腳本去遍歷,當(dāng)檢測(cè)到failed
的tasks
,進(jìn)行提醒。當(dāng)然他的界面也很直觀的看出。tasks
的參數(shù)(如上面的*args
會(huì)在頁面中顯示) - 使用
celery
的信號(hào)機(jī)制,當(dāng)task_failure
信號(hào)觸發(fā),可以發(fā)送提醒通知
好了,十分鐘我也只能做這些...回頭驗(yàn)證,接口規(guī)范再完善下