我有以下代码:
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/ping")
async def ping(request: Request):
print("Hello")
time.sleep(5)
print("bye")
return {"ping": "pong!"}
Run Code Online (Sandbox Code Playgroud)
如果我在本地主机上运行我的代码 - 例如http://localhost:8501/ping
- 在同一浏览器窗口的不同选项卡中,我得到:
Hello
bye
Hello
bye
Run Code Online (Sandbox Code Playgroud)
代替:
Hello
Hello
bye
bye
Run Code Online (Sandbox Code Playgroud)
我已经阅读过有关使用的内容httpx
,但仍然无法实现真正的并行化。有什么问题?
python asynchronous concurrent-processing python-asyncio fastapi
我有一个大的只读数据结构(在networkx中加载的图形,虽然这不应该很重要),我在我的Web服务中使用.Web服务是在Flask中构建的,然后通过Gunicorn提供服务.事实证明,对于我旋转的每个枪支工作者来说,这个工作都拥有我自己的数据结构副本.因此,当我有8个运行时,我的~700mb数据结构可以完全由一个工人管理,变成了一个非常大的内存.有没有什么方法可以在gunicorn进程之间共享这个数据结构,所以我不必浪费那么多内存?
我已经部署了一个 fastapi 端点,
from fastapi import FastAPI, UploadFile
from typing import List
app = FastAPI()
@app.post('/work/test')
async def testing(files: List(UploadFile)):
for i in files:
.......
# do a lot of operations on each file
# after than I am just writing that processed data into mysql database
# cur.execute(...)
# cur.commit()
.......
# just returning "OK" to confirm data is written into mysql
return {"response" : "OK"}
Run Code Online (Sandbox Code Playgroud)
我可以从 API 端点请求输出,它对我来说工作得很好。
现在,对我来说最大的挑战是知道每次迭代需要多少时间。因为在 UI 部分(那些访问我的 API 端点的人)我想帮助他们为正在处理的每个迭代/文件显示一个进度条(TIME TAKEN)。
我有什么可能的方法来实现它吗?如果是这样,请帮助我了解如何进一步处理?
谢谢你。
HTTP
如何在 FastAPI 的请求之间共享变量值?例如,我有一个POST
请求,其中我获取一些音频文件,然后将它们的信息转换为 Pandas Dataframe
。我想在请求Dataframe
中发送它GET
,但我无法访问Dataframe
请求GET
范围。
@app.post(
path="/upload-audios/",
status_code=status.HTTP_200_OK
)
async def upload_audios(audios: list[UploadFile] = File(...)):
filenames = [audio.filename for audio in audios]
audio_data = [audio.file for audio in audios]
new_data = []
final_data = []
header = ["name", "file"]
for i in range(len(audios)):
new_data = [filenames[i], audio_data[i]]
final_data.append(new_data)
new_df = pd.DataFrame(final_data, columns=header)
return f"You have uploaded {len(audios)} audios which names are: {filenames}"
@app.get("/get-dataframe/")
async def get_dataframe():
pass
Run Code Online (Sandbox Code Playgroud) 有没有一个很好的方法来分享gunicorn工人之间的多处理锁?我正在尝试用Flask编写一个json API.一些API调用将与管理正在运行的进程的python类进行交互(如用于视频转换的ffmpeg).当我将Web工作者的数量扩大到1以上时,如何确保只有1名工作人员同时与该班级进行交互?
我最初的想法是使用multiprocessing.Lock,所以start()函数可以是原子的.我不认为我已经找到了创建Lock的正确位置,以便在所有工作者之间共享一个:
# runserver.py
from flask import Flask
from werkzeug.contrib.fixers import ProxyFix
import dummy
app = Flask(__name__)
@app.route('/')
def hello():
dummy.start()
return "ffmpeg started"
app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == '__main__':
app.run()
Run Code Online (Sandbox Code Playgroud)
这是我的虚拟操作:
# dummy.py
from multiprocessing import Lock
import time
lock = Lock()
def start():
lock.acquire()
# TODO do work
for i in range(0,10):
print "did work %s" % i
time.sleep(1)
lock.release()
Run Code Online (Sandbox Code Playgroud)
当我刷新页面几次时,我看到每个调用的输出编织在一起.
我在这里吠叫错了吗?有没有更简单的方法来确保只有处理类的副本(这里只是虚拟start()方法)同时运行?我想我可能需要像celery这样的东西来运行任务(并且只使用1名工人),但这对我的小项目来说似乎有些过分.
我有一个简单的 fastApi 演示应用程序,它实现了一个功能:通过调用一个名为 changeResponse 的 post api 来获取不同的响应 json。changeResponse api 只是更改了一个全局变量,另一个 api 通过同一个全局变量返回了不同的响应。在本地环境中,它工作正常,但是当我在 docker 上构建它时,我只调用 changeResponse 一次后响应总是改变。代码如下如下:
from typing import Optional
from fastapi import FastAPI
from util import read_json
import enum
app = FastAPI()
type = "00"
@app.post("/changeResponse")
async def handle_change_download_response(param:Optional[str]):
global type
type = param
print("type is "+type)
return {"success":"true"}
@app.post("/download")
async def handle_download(param:Optional[str]):
print("get download param: "+param)
if legalDownload(param):
print("type is "+type)
return read_json.readDownloadSuccessRes(type)
else:
return read_json.readDownloadFailRes()
def legalDownload(data:str)->bool:
return True
Run Code Online (Sandbox Code Playgroud)
dockerfile 如下:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app …
Run Code Online (Sandbox Code Playgroud) 我想统计特定 URL 路径中的请求数。
app = FastAPI()
counter = 0
@app.get("/do_something")
async def do_something():
global counter
counter += 1
return {"message": "Hello World"}
Run Code Online (Sandbox Code Playgroud)
这段代码可以吗?计数器应该是线程安全的?阿辛西奥安全吗?这是计算请求的正确方法(没有数据库)吗?在这种情况下,“do_something”函数中的“async”有含义吗?以及如何让它与多个工人一起工作?
如果所有 fastapi 端点都定义为async def
,那么只会有 1 个线程在运行,对吗?(假设有一个独角兽工人)。
只是想确认在这样的设置中,我们永远不会遇到 python 的全局解释器锁。如果在一个具有多个线程的 Flask 框架中为单个 Gunicorn Worker 做同样的事情,那么我们将面临 GIL,它阻碍了线程之间真正的并行性。
所以基本上,在上面的 fastapi 中,并行度限制为 1,因为只有一个线程。为了利用所有核心,我们需要增加使用 Gunicorn 或 uvicorn 的工作人员数量。
我的理解正确吗?
我想将文件上传到 FastAPI 后端并将其转换为 Pandas DataFrame。但是,我似乎不明白如何使用 FastAPI 的UploadFile
对象来做到这一点。更具体地说,我应该将什么传递给该pd.read_csv()
函数?
这是我的 FastAPI 端点:
@app.post("/upload")
async def upload_file(file: UploadFile):
df = pd.read_csv("")
print(df)
return {"filename": file.filename}
Run Code Online (Sandbox Code Playgroud) python ×9
fastapi ×7
uvicorn ×4
gunicorn ×3
flask ×2
python-3.x ×2
api ×1
asgi ×1
asynchronous ×1
concurrency ×1
csv ×1
dataframe ×1
docker ×1
gil ×1
httprequest ×1
networkx ×1
pandas ×1
starlette ×1