TOC
小APP代码
import os
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory, jsonify, json
from werkzeug.utils import secure_filename
import time
from os.path import join, getsize
from utils import allowed_file, get_hash, unzip_file
import shutil
import process
ALLOWED_EXTENSIONS = {'zip'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './resources/source/'
app.config['ANALYZE_FOLDER'] = './resources/analyze/'
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
return render_template('404.html')
if file and allowed_file(file.filename, ALLOWED_EXTENSIONS):
filename = secure_filename(file.filename)
filePath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filePath)
file.close()
f = open(filePath, 'rb')
md5 = str(get_hash(f))
f.close()
workfile = app.config['ANALYZE_FOLDER'] + md5 + '/'
is_file_exist = os.path.exists(workfile)
if not is_file_exist:
unzip_file(filePath, workfile)
os.remove(filePath)
workpath = app.config['ANALYZE_FOLDER'] + md5 + '/'
analyze = process.Process(workpath)
ret = analyze.stat()
success_json = {
'url': '/' + md5,
'stat': ret,
}
return jsonify(success_json)
else:
ret = {
'init': {
'stat': False,
'msg': '文件格式错误,请上传正确格式的文件'
}
}
success_json = {
'stat': ret,
}
return jsonify(success_json)
return render_template('index.html',
allowedFile=ALLOWED_EXTENSIONS,
val=int(time.time()))
@app.route('/<md5>/')
def uploaded_file(md5):
return render_template('analyze.html',
val=int(time.time()))
@app.route( "/<md5>/", methods = [ "POST", "GET" ])
def getDataSet(md5):
send_data = {}
with open(app.config['ANALYZE_FOLDER'] + md5 + '/' + 'analyze.json', 'r') as load_json:
send_data = json.load(load_json)
load_json.close()
return jsonify(send_data)
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080, threaded=True, debug=True)
小坑
flask jinja模板显示图片
直接把图片路径填入jinja模板似乎是不行的,目前还没找到方法。能做的是在jinja模板中写入固定的url;或者将图片在后台解析成字符流,在传输给前端,不过这样造成的影响是,前端“不认为”这是一个图片。
- 后台
def return_img_stream(img_local_path):
import base64
img_stream = ''
with open(img_local_path, 'rb') as img_f:
img_stream = img_f.read()
img_stream = base64.b64encode(img_stream)
return img_stream
- 前端
<img src="data:;base64, {{ FrameRateImg }}", alt="***" >
但是因为是只需要展示图表,所以最后改成在后台做数据解析和整理的工作,再将数据发送到前端,由前端的d3.js做数据可视化工作。
flask ajax操作
尽量以json格式做数据传递的格式。
- 后台
@app.route( "/<md5>/", methods = [ "POST", "GET" ])
def getDataSet(md5):
send_data = {}
with open(app.config['ANALYZE_FOLDER'] + md5 + '/' + 'analyze.json', 'r') as load_json:
send_data = json.load(load_json)
load_json.close()
return jsonify(send_data)
- 前端
var analyze_path = window.location.pathname;
var request_data = {
"data": "reserved",
}
$.ajax({
type: 'POST',
url: analyze_path,
data: JSON.stringify(request_data),
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
success: function(data) {
draw(data);
},
error: function(xhr, type) {
console.log("can not get ajax retured");
}
});
部署
使用 gunicorn gevent docker
pip install gunicorn gevent
在gunicorn.conf.py中配置
workers = 5
worker_class = "gevent"
bind = "0.0.0.0:8080"
使用docker,在dockerfile中配置
FROM python:3.6
WORKDIR /www/
COPY requirements.txt .
RUN pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
COPY . .
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]
来源:oschina
链接:https://my.oschina.net/u/4341956/blog/4257898