一个flask服务,它能随时接收指定店铺id来计算交易信息,又可以在指定时间对所有店铺计算。
POST参数:
flag: #True为全部店铺,False为指定店铺
shop_id:# 可以为空,当flag=False时,必须有店铺id
随时接收POST body开始计算,半夜接收个全量flag。可刚巧看到个Click包,能碾压我之前常常使用得agrparser包,那我就让我的这个flask服务既能接收POST,也能使用crontab跟着指定参数定时跑吧。
原始flask服务:
from flask import Flask, request, jsonify
app = Flask(__name__)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=9965)
Click官方例子
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
for x in range(count):
print('Hello %s!' % name)
if __name__ == '__main__':
hello()
option 是最基本的,从命令行读取参数值并传递给方法。在上面的例子,我们看到,除了设置命令行选项的名称还有:
default: 设置命令行参数的默认值
help: 参数说明
type: 参数类型,可以是 string, int, float 等
prompt: 当在命令行中没有输入相应的参数时,会根据 prompt 提示用户输入
nargs: 指定命令行参数接收的值的个数
不应该使用@click装饰main方法,所以要把flask app 和全量店铺计算方法抠出来到一个方法,由click装饰:
@click.command()
@click.option('--mode', default="server", type=click.Choice(["server", "client"]), help="client run all shops, server receive specific seller_id")
def run(mode):
if mode == "server":
app.run(host='0.0.0.0', debug=True, port=9965)
else:
calc_all_shops()
if __name__ == '__main__':
run()
解释一下,click装饰run(),它根据命令行参数mode,如果mode是server, 它就是flask服务,接收需要计算的店铺id;如果mode=client, run()里面的判断接收到了参数,运行calc_all_shop()。mode参数只能接受server或者client,输入别的会报help信息哦。运行一下,报错了:
Traceback (most recent call last):
...
RuntimeError: Click will abort further execution because Python 3 was
configured to use ASCII as encoding for the environment. Either switch
to Python 2 or consult http://click.pocoo.org/python3/ for
mitigation steps.
click好像对Python3支持不大好哦,官方有文档说明:http://click.pocoo.org/5/python3/,当然也提供了临时解决办法:
export LC_ALL=de_US.utf-8
export LANG=de_US.utf-8
如果使用Pycharm调试的话,记得edit configuration里添加,不然还会继续报错哦:
好了,本地调好了,我们怎么部署这个服务呢?线上flask app可不能使用debug模式哦,也不能使用flask自带得web服务器哦,所以要引入gunicorn
nohup gunicorn main_server:app -b 0.0.0.0:9965 -w 4 &
凌晨03:01跑全量店铺计算:
1 3 * * * cd ~/所在目录; nohup ~/anaconda2/envs/python35/bin/python main_server.py --mode client >> allshop.log 2>&1 &