如何避免在python API服务器中重复处理? [英] How to avoid duplicate processing in python API server?
问题描述
假设函数detect_primes
的调用成本很高,我希望避免使用重复的参数重复调用它。我该怎么办?
def detect_primes(nums: List[int]) -> Dict[int, bool]:
""" detect whether a list of numbers are prime """
@app.route('/detect', methods=['GET'])
def search():
args = request.args
nums = list(map(int, args.get('nums', '').split(',')))
return detect_primes(nums)
例如,如果一个用户使用13,14,15进行请求,则另一个用户使用15,16进行请求。
答案是{"13": true, "14": false, "15": false}
和{"15": false, "16": false}
我希望避免使用[13, 14, 15]
和[15, 16]
调用detect_primes
。理想情况下,两个请求都应等待一个[13, 14, 15, 16]
调用(或两个调用[13, 14, 15]
和[16]
),并返回各自的结果。
选择Web框架对我来说并不重要,您可以假设它是FASK或FastAPI。
编辑:不确定问题如何与Are global variables thread-safe in Flask? How do I share data between requests?重复或在Are global variables thread-safe in Flask? How do I share data between requests?中得到回答,不能使用缓存(无论是内存中的Python缓存还是外部缓存或数据库)。我很高兴被一个答案证明是错的。
推荐答案
在声明路径运算函数时使用Normaldef
,而不是async def
,它在一个外部线程池中运行, 而不是直接调用(因为它会阻止服务器)。
因此,当您使用def
而不是async def
时,服务器会并发处理请求。
在您的情况下--由于您将其描述为&qot;理想情况下,两个请求都应该等待...&q;--您可以用async def
声明search
路由。异步路由在主线程上运行,服务器按顺序处理请求(只要这样的路由内没有await
调用)。通过这种方式,您可以使用字典缓存以前的(已经计算出的)数字,并使用它在后续请求中快速查找数字。您还可以使用类似于this的方法来限制词典的大小。下面给出了例子。您可以通过http://127.0.0.1:8000/docs处的OpenAPI或使用http://127.0.0.1:8000/?nums=13&nums=14&nums=15之类的URL来测试以下内容。
from fastapi import FastAPI, Query
from typing import List, Dict
app = FastAPI()
d = {}
def is_prime(n) -> bool:
# check whether 'n' is prime or not
def detect_primes(nums: List[int]) -> Dict[int, bool]:
res = {}
for n in nums:
if n in d:
res[n] = d.get(n)
print(f'{n} found in dict')
else:
is_n_Prime = is_prime(n)
res[n] = is_n_Prime
d[n] = is_n_Prime
return res
@app.get("/detect")
async def search(nums: List[int] = Query(...)):
return detect_primes(nums)
这篇关于如何避免在python API服务器中重复处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!