【Python开发】FastAPI 11:构建多文件应用

news2024/11/15 7:31:48

以往的文件都是将对外接口写在一个文件里边,而作为应用来说,接口是不可避免分散到多个文件中的,比如某文件负责注册登录模块,某文件负责内管模块,某文件负责业务模块等。FastAPI 也提供了APIRouter 这一工具来进行灵活构建应用,本文将是它的示例。

目录

1 APIRouter

1.1 APIRouter 使用

1.2 其他模块的引入

2 app 项目示例

2.1 文件结构

2.2 其他 文件

2.3 main 文件

2.4 API 文档


📌 源码地址:

https://gitee.com/yinyuu/fast-api_study_yinyu

1 APIRouter

大家可以看到,前边的示例均是以 app = FastAPI() 作为路由,但是它只适合小项目,如果接口按模块进行划分就不满足了。而 APIRouter 正实现了接口按模块的功能,以使其井井有条。

1.1 APIRouter 使用

类似 app = FastAPI()

from fastapi import APIRouter #导入 APIRouter

router = APIRouter()

@router.get("/users/", tags=["users"])
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]

可以将 APIRouter 视为一个小号 FastAPI 类,所有相同的选项都得到支持,比如 parameters、responses、dependencies、tags 等等。

此示例中,该变量被命名为 router,但你可以根据你的想法自由命名。

1.2 其他模块的引入

类似 FastAPI ,我们还可以通过 prefixtagsdependencies responses 等参数来减少重复代码和增加效率。比如有两个接口:

  • /items/
  • /items/{item_id}

他们的路径前缀一样,那么我们通过以下方式简化代码:

  • prefix:/items,前缀,不能以 / 作为结尾,不然回合路径重合
  • tags:items 标签,主要在 api 文档中用于分类
  • responses:额外的响应模型,所有接口都将拥有
  • dependencies:依赖,比如 get_token_header 依赖项。
from fastapi import APIRouter, Depends, HTTPException
 
from ..dependencies import get_token_header #通过 .. 对依赖项使用了相对导入,具体代码可看第二章

router = APIRouter(
    prefix="/items",
    tags=["items"],
    dependencies=[Depends(get_token_header)],
    responses={404: {"description": "Not found"}},
)

@router.get("/")
async def read_items():
    return fake_items_db

@router.get("/{item_id}")
async def read_item(item_id: str):
    if item_id not in fake_items_db:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"name": fake_items_db[item_id]["name"], "item_id": item_id}

最终结果是项目相关的路径现在为:

  • /items/
  • /items/{item_id}

2 app 项目示例

接下来以 app 项目为例,展示一下多文件应用的构建。

2.1 文件结构

📌 结构如下:

app 目录包含了所有内容,他是一个 Python 包:

  • app/main.pymain 模块,也是项目的主文件,或者说启动类
  • app/dependencies.py:存放依赖项
  • app/routers/ :Python 子包:
    • app/routers/items.py:存放 ietms 相关接口
    • app/routers/users.py:存放 users 相关接口
  • app/internal/ :Python 子包:
    • app/internal/admin.py:内管相关接口

2.2 其他 文件

📌 dependencies.py

依赖项相关方法,验证请求体和 token ~

from fastapi import Header, HTTPException

async def get_token_header(x_token: str = Header()):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")

async def get_query_token(token: str):
    if token != "jessica":
        raise HTTPException(status_code=400, detail="No Jessica token provided")

📌 items.py

from fastapi import APIRouter, Depends, HTTPException

from ..dependencies import get_token_header

router = APIRouter(
    prefix="/items",
    tags=["items"],
    dependencies=[Depends(get_token_header)],
    responses={404: {"description": "Not found111"}},
)

fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}

@router.get("/")
async def read_items():
    return fake_items_db

@router.get("/{item_id}")
async def read_item(item_id: str):
    if item_id not in fake_items_db:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"name": fake_items_db[item_id]["name"], "item_id": item_id}

@router.put(
    "/{item_id}",
    tags=["custom"],
    responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):
    if item_id != "plumbus":
        raise HTTPException(
            status_code=403, detail="You can only update the item: plumbus"
        )
    return {"item_id": item_id, "name": "The great Plumbus"}

📌 users.py

from fastapi import APIRouter

router = APIRouter()

@router.get("/users/", tags=["users"])
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]

@router.get("/users/me", tags=["users"])
async def read_user_me():
    return {"username": "fakecurrentuser"}

@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):
    return {"username": username}

📌 users.py

from fastapi import APIRouter

router = APIRouter()

@router.post("/")
async def update_admin():
    return {"message": "Admin getting schwifty"}

以上接口文件均使用 APIRouter ,最后将调用给 main 文件以供汇总。

2.3 main 文件

这里你导入并使用 FastAPI 类,是应用程序中将所有内容联结在一起的主文件。 

from fastapi import Depends, FastAPI

from .dependencies import get_query_token, get_token_header
from .internal import admin
from .routers import items, users

app = FastAPI(dependencies=[Depends(get_query_token)])

app.include_router(users.router)
app.include_router(items.router)
app.include_router( #依旧可自定义参数
    admin.router,
    prefix="/admin",
    tags=["admin"],
    dependencies=[Depends(get_token_header)],
    responses={418: {"description": "I'm a teapot"}},
)

@app.get("/")
async def root():
    return {"message": "Hello Bigger Applications!"}


if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

📌 导入模块

比如:

from .routers import items, users
  • 这表示从该模块(app/main.py 文件)所在的同一个包(app/ 目录)
  • 寻找 routers 子包(位于 app/routers/ 的目录)...
  • 从该包中,导入子模块 items (位于 app/routers/items.py 的文件) 以及 users (位于 app/routers/users.py 的文件)...

items 模块将具有一个 router 变量(items.router)。

相对导入:from .routers import items, users

绝对导入:from app.routers import items, users

📌 app.include_router

app.include_router(users.router)
app.include_router(items.router)

使用 app.include_router(),我们可以将每个 APIRouter 添加到主 FastAPI 应用程序中。 它将包含来自该路由器的所有路由作为其一部分。

官方:包含路由器时,你不必担心性能问题。 这将花费几微秒时间,并且只会在启动时发生。 因此,它不会影响性能。⚡

2.4 API 文档

启动 main 文件,访问 http://127.0.0.1:8000/docs,即可看到使用了正确路径(和前缀)和正确标签的自动化 API 文档,包括了来自所有子模块的路径:

由于 fastapi 内置的接口文档使用的外网的 cdn,所以可能导致页面卡死,接口文档显示空白,解决办法可参考:https://blog.csdn.net/m0_52726759/article/details/124854070。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kafka消息队列的初步探索

消息队列的作用就是提高运行速度,防止线程堵塞。 kafka的作用 异步 通过在消息队列发送消息的方式,将对应的业务作为监听者,此时我们只需要考虑发送消息的时间即可,大大提高了运行的速度。 解耦 如果使用原来的直接调用对应业务的…

【libdatachannel】pycharm运行streamer的信令服务及streamer与js客户端联调

启动py服务器 ssl必须额外指定 # Usage: ./server.py [[host:]port] [SSL certificate file]文档给出了服务的启动命令: python3 -m http.server --bind 127.0.0.1 8080 直接运行: python的信令服务 #!/usr/bin/env python # # Python signaling server…

需求分析引言:架构漫谈(二)非功能性需求

上一篇文章,简要介绍了架构的概念和架构设计流程,并简单介绍了需求分析的内容, 并在最后指出:需求分析的产出物,要包括非功能性需求,常见的非功能性需求如下: 完成任务的速度结果的精度操作的安…

MySQL实战解析底层---为什么表数据删掉一半,表文件大小不变

目录 前言 参数innodb_file_per_table 数据删除流程 重建表 Online 和 inplace 前言 数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?这与数据库表的空间回收有关这里还是针对MySQL中应用最广泛的InnoD…

结构型设计模式07-享元模式

🧑‍💻作者:猫十二懿 ❤️‍🔥账号:CSDN 、掘金 、个人博客 、Github 🎉公众号:猫十二懿 享元模式 1、享元模式介绍 享元模式是一种结构型设计模式,旨在**通过共享对象来减少内存使…

CSS弹性布局常用设置

目录 一、单位元素 二、弹性容器 三、常用属性 三、项目实战效果 一、单位元素 vm 1vm 为视口的1% vh 视口高的1% vmin 参照长边 vmax 参照长边 rem 等比缩放 需要设置最外层盒子html设置vw 根字号html的--- font-- 1vm 去适配 初始化 //初始化*{padding: 0;margin: 0}//…

机器学习笔记 - 通过一个例子来快速理解自注意力机制/缩放点积注意力机制

一、一个简单的示例 请看下面的例句:A dog ate the food because it was hungry(一只狗吃了食物,因为它很饿) 例句中的代词it(它)可以指代dog(狗)或者food(食物)。当读这段文字的时候,我们自然而然地认为it指代的是dog,而不是food。但是当计算机模型在面对这两种选…

CVPR首个大模型研讨会顺利召开,吸引超1000支队伍参与文心大模型国际比赛

CVPR 作为计算机视觉和模式识别领域的世界级学术顶会,不仅是学者们展示前沿科技成果的学术会议,也是企业界探索前沿应用的一大平台。近年来,随着大模型技术的爆发式发展,基于大模型技术的创新应用正逐步在产业界释放出巨大价值空间…

网易云信陈丽:做泛娱乐出海新浪潮中的坚实助力者

6 月 16 日下午,在 PAGC 2023 泛娱乐出海论坛上,网易智企副总经理、网易云信总经理陈丽分享了对全球化出海的趋势洞察和未来展望,并介绍了网易云信在帮助泛娱乐出海业务增长方面的探索和实践。 陈丽表示,网易云信志在成为中国开发…

STM32开发——非标协议(DH11+LCD1602)

1.STM32分文件实现代码 编译的总文件夹dh11andlcd,C文件不能跨文件夹查找,新增的分文件,需要都放调用的文件夹下 C文件和H文件理解:H文件是门脸,放在前面给别人的,别人一看就知道有什么东西。C是给内部人用…

记录--新的HTML标签 :search

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 本文介绍了一种新的HTML元素搜索方法,并提供了一个实用的工具来帮助开发者快速找到所需的元素。这对于那些需要处理大量HTML元素的开发者来说是非常有用的。文章还通过提供一些常见元素的用…

AutoSAR系列讲解(入门篇)1.1-AutoSAR的发展史

一、AutoSAR成员 大体可以分为核心成员、高级成员和发展成员,可以打开AutoSAR官网的成员的介绍界面 所以有兴趣的小伙伴可以稍微了解一下,仅作了解就行,不是什么重要的知识 还有一张大家经常能看见的成员图,如下 二、AutoSAR历史…

国潮之美丨土家族西兰姑娘续写千年非遗传奇

光脚丫,童年时期的行为艺术 还记得儿时的夏夜,姥爷总说:“娃儿呀,光着脚在地上跑,接地气些”。那时只觉得脱掉鞋袜顿时轻松自在,从坡上冲到坡下,几个伙伴乐此不疲。后来长大了,穿着…

盘点一个Python网络爬虫过验证码的问题(方法一)

点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 低眉信手续续弹,说尽心中无限事。 大家好,我是皮皮。 一、前言 前几天在Python最强王者群【鶏啊鶏。】问了一个Python网络爬虫的…

SSH连接异常:从迷茫到石破天惊的解决之道

文章目录 零:前言一:SSH1.1 SSH的连接类型、方式和端口1.2 常见端口及其类型 二:解决SSH连接异常第一步:欣赏报错,顺藤摸瓜第二步:异常窥探,摸石过河第三步:问题确定,斩首…

测试技术体系

目录: 软件测试分类分层测试体系 1.软件测试分类 软件测试的分类_安全性测试属于功能测试吗_阿瞒有我良计15的博客-CSDN博客 1.单元测试(Unit Testing):单元测试是指对软件的最小可测试单元进行测试,例如一个函数、一…

Cell — 新“出芽”方法为疫苗开发带来优势

在疫苗学中,基于mRNA向体内递送抗原编码基因同基于纳米颗粒向体内递送抗原在应对具有挑战性的病原体方面都显示出巨大的前景。本期的《Cell》中,Hoffmann等人将两种方法相结合,通过调节被许多病毒劫持的相同细胞代谢通路来增强SARS-CoV-2疫苗…

【UCOS-III】自我学习笔记→第27讲→优先级翻转

文章目录 前言实验步骤1.复制二值信号量工程,添加task2和task3,修改任务服务函数名称2.修改开始任务,任务1以及任务2、3的内容3.查看串口现象![在这里插入图片描述](https://img-blog.csdnimg.cn/efa5ee2d92b54fe8be5a419adcf92ead.png) 测试…

STM32速成笔记—DMA

文章目录 一、什么是DMA二、DMA有什么作用三、STM32的DMA3.1 DMA请求3.2 DMA通道3.3 仲裁器 四、DMA配置4.1 DMA配置步骤4.2 DMA结构体成员 五、DMA配置程序5.1 ADC1初始化程序5.2 DMA初始化程序 一、什么是DMA DMA全程Direct Memory Access,即直接存储器访问。简单…

如何保护阿里云服务器免受DDoS攻击和恶意访问?有哪些防护措施?

如何保护阿里云服务器免受DDoS攻击和恶意访问?有哪些防护措施?   [本文由阿里云代理商[聚搜云]撰写]   随着互联网技术的不断发展,网络安全问题日益严峻,保护服务器免受DDoS攻击和恶意访问成为了每个企业和网站建设者的关注重…