Python-在Flask中将查询结果从服务器返回到客户端 [英] Python - Returning query result from server to client in Flask

查看:437
本文介绍了Python-在Flask中将查询结果从服务器返回到客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  • 我拥有的东西

我在Flask中有一个客户端/服务器。客户端将JSON格式的查询发送到服务器,并且服务器创建JSON文件。还有另一个工具可以接受此查询,在数据库上执行该查询,然后将结果写入results.txt文件。服务器会定期检查结果目录中的.txt文件,如果找到新文件,它将提取结果。对于定期检查,我使用了APS。

I have a Client/Server in Flask. The client sends a query in JSON format to the server and the server creates a JSON file. There is another tool which takes this query, executes it on a db and writes the result to a results.txt file. The server periodically checks the 'results' directory for .txt files and if it finds a new file it extracts the result. For the periodic checking part I used APS.

我想做什么
现在我要将服务器从.txt文件中提取的数据(queryResult)发送回客户端。

What I want to do Now I want to send this data (queryResult) which the server has extracted from the .txt file back to the client.


  • 服务器代码:

  • Server Code:

app = Flask(__name__)
api = Api(app)

# Variable to store the result file count in the Tool directory
fileCount = 0

# Variable to store the query result generated by the Tool
queryResult = 0    
    
# Method to read .txt files generated by the Tool
def readFile():
    global fileCount
    global queryResult
    # Path where .txt files are created by the Tool
    path = "<path>"
    tempFileCount = len(fnmatch.filter(os.listdir(path), '*.txt'))
    if (fileCount != tempFileCount):
        fileCount = tempFileCount
        list_of_files = glob.iglob(path + '*.txt')
        latest_file = max(list_of_files, key=os.path.getctime)
        print("\nLast modified file: " + latest_file)
        with open(latest_file, "r") as myfile:
            queryResult = myfile.readlines()
            print(queryResult) # I would like to return this queryResult to the client
            
scheduler = BackgroundScheduler()
scheduler.add_job(func=readFile, trigger="interval", seconds=10)
scheduler.start()   

# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())   
   
# Method to write url parameters in JSON to a file
def write_file(response):
    time_stamp = str(time.strftime("%Y-%m-%d_%H-%M-%S"))  
    with open('data' + time_stamp + '.json', 'w') as outfile:
        json.dump(response, outfile)
    print("JSON File created!")
   

class GetParams(Resource):
    def get(self):
        response = json.loads(list(dict(request.args).keys())[0])  
        write_file(response)  
           
api.add_resource(GetParams, '/data')  # Route for GetJSON()

if __name__ == '__main__':
    app.run(port='5890', threaded=True)




  • 客户代码

    • Client Code

    • data = {
          'query': 'SELECT * FROM table_name'
      }
      
      url = 'http://127.0.0.1:5890/data'
      
      session = requests.Session()
      retry = Retry(connect=3, backoff_factor=0.5)  
      adapter = HTTPAdapter(max_retries=retry)
      session.mount('http://', adapter)
      session.mount('https://', adapter)
      
      resp = session.get(url, params=json.dumps(data))
      print(resp)
      


      可以任何人都可以帮助我如何将这个queryResult发送回客户端?

      Can anyone please help me as to how to send this queryResult back to the Client?

      编辑:我希望服务器在每次遇到新文件时都将queryResult发送回客户端。工具目录,即每次找到新文件时,都会提取结果(当前正在执行)并将其发送回客户端。

      I would like the server to send the queryResult back to the client each time it encounters a new file in the Tool directory i.e., every time it finds a new file, it extracts the result (which it is doing currently) and send it back to the client.

      推荐答案

      您要执行的操作称为 Web Worker体系结构

      What you want to do is called a Web Worker Architecture.

      要将实时抽象 queryResult 从后台作业传递到客户端应用程序,您可以组合使用消息队列(建议使用Kafka,RabbitMQ也可以)和Web套接字。当客户端向 / data 端点发送请求时,您应该返回一些唯一的令牌(例如,如果您的用户是匿名用户,则为UUID;如果已通过身份验证,则为用户ID)。您应该在结果文件的名称中添加相同的标记。当后台工作人员完成文件处理后,它使用令牌(来自文件名)创建Kafka或RabbitMQ主题,例如 topic_for_user_id_1337 topic_for_uuid_jqwfoj- 123qwr ,并发布 queryResult 作为消息。

      To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.

      同时,您的客户端应该建立一个网络套接字连接(Flask对于网络套接字来说是相当糟糕的,但是反正套接字socketio却很少这样做)并将令牌通过令牌传递到您的后端,这样它将创建一个消息队列订阅者,使用该令牌的名称订阅了一个主题,因此当后台作业完成时,网络后端将收到一条消息,并将其通过网络套接字传递给用户。

      At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.

      聚苯乙烯如果听起来过于复杂,则可以避免使用MQ和WS,并将 queryResult 放入数据库中,并创建一个端点以检查其是否存在于数据库中。如果还没有,则返回类似尚未准备好的内容,如果准备就绪,客户端会在几秒钟内重试-您返回 queryResult 来自数据库。

      P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.

      这篇关于Python-在Flask中将查询结果从服务器返回到客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆