FastAPI的应用程序安装是如何工作的?

2024-05-23 11:34:01 发布

您现在位置:Python中文网/ 问答频道 /正文

出于某些原因,我们选择了FastAPI,以便将其用作我们多模块产品的后端层。它的一个吸引人的特性是子应用程序,它帮助我们分离不同的模块,以使其更加模块化。但我们对官方文件中缺失的一些可能的缺陷表示关注。我们需要通过插件、中间件和依赖注入在主模块和子模块之间共享大量的公共内容,例如数据、服务等。问题是:这个功能对于单独的模块足够好吗?以及:子应用程序是否继承了来自父应用程序的中间件、插件和依赖注入?

感谢您分享您的经验

the sample code in the official docs

from fastapi import FastAPI

app = FastAPI()


@app.get("/app")
def read_main():
    return {"message": "Hello World from main app"}


subapi = FastAPI()


@subapi.get("/sub")
def read_sub():
    return {"message": "Hello World from sub API"}


app.mount("/subapi", subapi)

Tags: 模块中间件thefrom插件app应用程序message
1条回答
网友
1楼 · 发布于 2024-05-23 11:34:01

我认为文档对此非常清楚

"Mounting" means adding a completely "independent" application.

无论如何,让我们继续从你的例子

这就是我们的subapi路线

[{"path":route.path} for route in subapi.routes] = [
     {'path': '/openapi.json'},
     {'path': '/docs'},
     {'path': '/docs/oauth2-redirect'},
     {'path': '/redoc'},
     {'path': '/sub'}
     ]

这是我们为应用程序的路线得到的

[{"path":route.path} for route in app.routes] = [{'path': '/openapi.json'},
     {'path': '/docs'},
     {'path': '/docs/oauth2-redirect'},
     {'path': '/redoc'},
     {'path': '/app'},
     {'path': '/subapi'}
     ]

这很有趣,因为我们的subapi没有继承/app,让我们继续,让事情变得更有趣,让我们用一个命令运行我们的应用程序

uvicorn my_app_name:app 
  • 正如所料,我们在/docs中有我们的应用程序文档

  • 另外,我们在/subapi/docs中有subapi的文档,这里没有什么有趣的东西

那么,当我们加上这个时,我们应该期待什么呢

subapi.mount("/app", app)

让我们再次运行它,但这次让我们调用subapi

uvicorn my_app_name:subapi

我们期望看到什么

  • 默认情况下,我们应该在/docs
  • 应用程序的文档位于/app/docs

是的,我们是对的,但事情从这里开始变得有趣

现在我们有了一个类似Matryoshka玩偶的应用程序

当我们向/app/subapi/sub发送请求时(提醒我们使用uvicorn my_app_name:subapi运行应用程序)

curl http://127.0.0.1:8000/app/subapi/sub

Out: {"message":"Hello World from sub API"}

看起来效果不错,但让我们再试一次

/app/subapi/app/subapi/app/subapi/app/subapi/app/subapi/app/app

curl http://127.0.0.1:8000/app/subapi/app/subapi/app/subapi/app/subapi/app/subapi/app/app

Out: {"message":"Hello World from main app"}

你糊涂了吗?别担心,让我解释一下

挂载子应用程序时,FastAPI使用ASGI规范中称为root_path的机制处理挂载的应用程序

{}是做什么的?为什么上面的例子有效

直截了当的root_path表示,您可以从root_path访问在app.routes中定义的所有路由,让我们将其可视化

现在我们的root_path/app

/app/

让我们添加subapi,它就成了我们的root_path

/app/subapi/

让我们再次添加应用程序,它就成了我们的root_path

/app/subapi/app
  • 注意:上面的例子之所以有效,是因为我们一起安装了两个应用程序

你不满意吗?你是说如果我添加一个中间件,会发生什么

很容易回答,它不会继承

让我用一个简单的例子来解释这一点,我将为我的subapi添加一个中间件

from fastapi.middleware.cors import CORSMiddleware

subapi.add_middleware(CORSMiddleware)

应用程序的所有数据都在__dict__

因此,我们可以通过检查“user\u middleware”键轻松找出差异

subapi.__dict__['user_middleware'] = [Middleware(CORSMiddleware)]
app.__dict__['user_middleware'] = []

您添加的所有其他东西都将独立工作,因为它们下面是完全不同的应用程序,所以您将安全地使用安装

结论

  • 是的,他们将独立工作。

相关问题 更多 >

    热门问题