优化 python 函数获取多级 json 属性

Optimise python function fetching multi-level json attributes

我有一个 3 级 json 文件。我正在从 json 的 3 个级别中的每个级别获取某些属性的值。目前,我的代码的执行时间很可怜,因为它需要大约 2-3 分钟才能在我的网页上获得结果。我将有一个更大的 json 文件来处理生产。

我是 python 和 flask 的新手,并没有做过很多网络编程。请建议我可以优化以下代码的方法!感谢您的帮助,非常感谢。

import json
import urllib2
import flask
from flask import request
def Backend():
    url = 'http://localhost:8080/surveillance/api/v1/cameras/'
    response = urllib2.urlopen(url).read()
    response = json.loads(response)
    components = list(response['children'])
    urlComponentChild = []
    for component in components:
        urlComponent = str(url + component + '/')
        responseChild = urllib2.urlopen(urlComponent).read()
        responseChild = json.loads(responseChild)
        camID = str(responseChild['id'])
        camName = str(responseChild['name'])
        compChildren = responseChild['children']
        compChildrenName = list(compChildren)
        for compChild in compChildrenName:
                href = str(compChildren[compChild]['href'])
                ID = str(compChildren[compChild]['id'])
                urlComponentChild.append([href,ID])
    myList = []
    for each in urlComponentChild:
        response = urllib2.urlopen(each[0]).read()
        response = json.loads(response)
        url = each[0] + '/recorder'
        responseRecorder = urllib2.urlopen(url).read()
        responseRecorder = json.loads(responseRecorder)
        username = str(response['subItems']['surveillance:config']['properties']['username'])
        password = str(response['subItems']['surveillance:config']['properties']['password'])
        manufacturer = str(response['properties']['Manufacturer'])
        model = str(response['properties']['Model'])
        status = responseRecorder['recording']
        myList.append([each[1],username,password,manufacturer,model,status])
    return myList
APP = flask.Flask(__name__)
@APP.route('/', methods=['GET', 'POST'])
def index():
    """ Displays the index page accessible at '/'
    """
    if request.method == 'GET':
        return flask.render_template('index.html', response = Backend())
if __name__ == '__main__':
    APP.debug=True
    APP.run(port=62000)

好的,缓存。因此,我们要做的是根据我们已有的数据立即开始 return 为用户提供价值,而不是每次都生成新数据。这意味着用户获得的最新数据可能比理论上可能获得的数据少一些,但这意味着他们收到的数据在给定您正在使用的系统的情况下会尽快收到。

因此我们将保持您的后端功能不变。就像我说的,你当然可以用多线程加速它(如果你仍然对此感兴趣,10 秒版本是我会使用 grequests 从 url 列表异步获取数据)。

但是,我们不会在每次用户请求数据时调用它来响应用户,而是每隔一段时间例行调用一次。无论如何,这几乎肯定是您最终想要做的事情,因为这意味着您不必为每个用户生成全新的数据,这是非常浪费的。我们会在一个变量中保留一些手头的数据,尽可能频繁地更新该变量,并且 return 每次我们收到新请求时都会更新该变量中的任何内容。

from threading import Thread
from time import sleep

data = None

def Backend():
    .....

def main_loop():
    while True:
        sleep(LOOP_DELAY_TIME_SECONDS)
        global data
        data = Backend()

APP = flask.Flask(__name__)
@APP.route('/', methods=['GET', 'POST'])
def index():
    """ Displays the index page accessible at '/'
    """
    if request.method == 'GET':
        # Return whatever data we currently have cached
        return flask.render_template('index.html', response = data)
if __name__ == '__main__':
    data = Backend() # Need to make sure we grab data before we start the server so we never return None to the user
    Thread(target=main_loop).start() #Loop and grab new data at every loop
    APP.debug=True
    APP.run(port=62000)

免责声明:我之前在几个项目中使用过 Flask 和线程,但我绝不是这方面或 Web 开发方面的专家。在将此代码用于任何重要的事情之前测试它(或者更好的是,在将它用于任何重要的事情之前找到知道他们正在做的人)

编辑:数据必须是全局的,对此感到抱歉 - 因此免责声明