![](/img/trans.png)
[英]How to speed up returning a 20MB Json file from a Python-Flask application?
[英]How to speed up JSON for a flask application?
我目前正在 Flask 中實現一個 webapp。 這是一個對收集到的數據進行可視化的應用程序。 每個頁面或部分將始終有一個 GET 調用,每個調用將返回一個 JSON 響應,然后將其處理為顯示數據。
當前的問題是在函數返回 JSON 響應之前需要進行一些計算。 這會導致某些響應的到達速度比其他響應慢,從而使頁面加載速度變慢。 我該如何正確處理? 我已經閱讀了 Flask 中的緩存,並想知道這是否是應用程序現在需要的。 我還對實現 Redis-Queue 進行了一些研究。 我不確定哪種方法是正確的。
任何幫助或見解將不勝感激。 提前致謝
這里有一些想法:
如果用於計算的源數據不太可能經常更改,則可以運行一次計算並保存結果。 然后,只要源數據保持不變,就可以直接提供結果。
您可以將結果保存回數據庫,也可以按照建議將它們保存在更快的存儲中,例如Redis。 根據您的描述,我懷疑最大的性能提升將在於不那么頻繁地進行計算,相比之下,存儲在常規數據庫與Redis或類似數據庫之間的差異可能並不明顯。
如果數據經常變化,那么您仍然需要經常進行計算。 在這種情況下,您必須選擇將計算推入客戶端。 您的Flask應用程序可以僅以JSON格式返回源數據,然后瀏覽器可以在用戶計算機上進行處理。
我希望這有幫助。
可以使用 copy_current_request_context 和 Redis, Thread
當您需要長時間進行 JSON 響應時,它會很有幫助。 第一個請求可能很慢,但下一個請求會更快。
例子
from datetime import timedelta, datetime
from threading import Thread
from . import dbb, redis_client
from flask import Blueprint, request, jsonify, flash, after_this_request, copy_current_request_context, \
current_app, send_from_directory
from .models import Shop, Customers
def save_customer_json_to_redis(request):
response_json = {
"have_customer": False,
"status": False,
"anythingelse": None,
"message":"False, you have to check..."
}
#print(request.data)
headers = request.headers
Authorization = headers['Authorization']
token = Authorization.replace("Bearer", "")
phone = request.args.get('phone')
if phone is not None and phone != "":
print('token', token, "phone", phone)
now = datetime.utcnow() + timedelta(hours=7)
shop = Shop.query.filter(Shop.private_token == token, Shop.ended_date > now, Shop.shop_active == True).first()
customer = Customers.query.filter_by(shop_id=shop.id, phone=phone).first()
if customer:
redis_name = f'{shop.id}_api_v2_customer_phone_{phone}_customer_id_{customer.id}'
print(redis_name)
response_json["anythingelse"] = ...# do want you want, it need long time to do
response_json["status"] = True
response_json["message"] = "Successful"
redis_client.set(redis_name, json.dumps(response_json)) #Save JSON to Redis
@app.route('/api/v2/customer', methods=['GET'])
def api_customer():
@copy_current_request_context
def do_update_customer_to_redis():# this function to save JSON you want to response next time to Redis
save_customer_json_to_redis(request)
Thread(target=do_update_customer_to_redis).start()
response_json = {
"have_customer": False,
"status": False,
"anythingelse": {},
"message": "False, you have to check..."
}
#print(request.data)
headers = request.headers
Authorization = headers['Authorization']
token = Authorization.replace("Bearer", "")
phone = request.args.get('phone')
if phone is not None and phone != "":
print('token', token, "phone", phone)
now = datetime.utcnow() + timedelta(hours=7)
shop = Shop.query.filter(Shop.private_token == token, Shop.ended_date > now,Shop.shop_active == True).first()
customer = Customers.query.filter_by(shop_id=shop.id, phone=phone).first()
if customer:
redis_name = f'{shop.id}_api_v2_customer_phone_{phone}_customer_id_{customer.id}'
print(redis_name)
try:
response_json = json.loads(redis_client.get(redis_name)) # if have json from app
print("json.loads(redis_client.get(redis_name))")
except Exception as e:
print("json.loads(redis_client.get(redis_name))", e)
#do any thing you want to response json
response_json["anythingelse"] = ...# do want you want, it need long time to do
response_json["message"]= ...#do want you want
#redis_client.set(redis_name, json.dumps(response_json))
response_json["status"] = True
response_json["message"] = "Successful"
return jsonify(response_json)
在初始化.py
from flask import Flask
from flask_cors import CORS
from flask_mail import Mail
from flask_sqlalchemy import SQLAlchemy
from redis import Redis
# init SQLAlchemy so we can use it later in our models
dbb = SQLAlchemy(session_options={"autoflush": False})
redis_client = Redis(
host='localhost',
port='6379',
password='your_redis_password'
)
def create_app():
app = Flask(__name__)
...........
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.