FastAPI,uvicorn.run() 总是创建 3 个实例,但我想要 1 个实例

Joh*_*ohn 12 python fastapi uvicorn

我在 PyCharm IDE 上运行 FastAPI,它总是运行 3 个工作线程。我不知道为什么,但是,每次 API 调用都会访问最后创建的实例。

谁能帮助我如何获得单一运行的工人?

代码:

import uvicorn
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from starlette.middleware.cors import CORSMiddleware

app = FastAPI()
app.add_middleware(CORSMiddleware,
                   allow_origins=["*"],
                   allow_methods=["*"],
                   allow_headers=["*"])
print(f"main.py with :{app}")


@app.get('/')
def home():
    return "Hello"


if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=False, log_level="debug", debug=True,
                workers=1, limit_concurrency=1, limit_max_requests=1)
Run Code Online (Sandbox Code Playgroud)

控制台输出:

/Users/user/.pyenv/versions/3.7.10/bin/python /Users/user/github/my-project/backend/main.py
main.py with :<fastapi.applications.FastAPI object at 0x102b35d50>
INFO:     Will watch for changes in these directories: ['/Users/user/github/my-project/backend']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [96259] using statreload
main.py with :<fastapi.applications.FastAPI object at 0x10daadf50>
main.py with :<fastapi.applications.FastAPI object at 0x1106bfe50>
INFO:     Started server process [96261]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
Run Code Online (Sandbox Code Playgroud)

Emm*_*Lin 20

感谢您最后的评论,我更好地理解了您的问题。

你真正的问题

所以实际上你的问题是为什么FastAPI对象被创建了 3 次。

在日志中确实可以看到你有3个不同的内存地址0x102b35d50,,0x10daadf500x1106bfe50

这并不意味着您有 3 个工作线程,只是该FastAPI对象被创建了 3 次。最后一项是您的 API 将使用的一项。

为什么会发生这种情况

该对象被创建多次,因为:

  1. 首先,您运行main.py它遍历所有代码(一次创建FastAPI对象),然后到达__main__
  2. 然后uvicorn启动,main:app以便它再次进入文件main.py并构建另一个FastAPI对象。
  3. 最后一个是由当debug=True您将其设置为 False 时创建的,您会少FastAPI创建一个对象。我不太清楚为什么。

解决方案

解决方案是将 API 定义与 API 开头分开。

例如,可以run.py使用以下内容创建一个文件:

import uvicorn

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=False, log_level="debug", debug=True,
                workers=1, limit_concurrency=1, limit_max_requests=1)

Run Code Online (Sandbox Code Playgroud)

并启动该文件。

另一种选择是在命令行中启动 API:

uvicorn main:app --host=0.0.0.0 --port=8000 --log-level=debug --limit-max-requests=1 --limit-concurrency=1
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到所有命令行参数