FastAPI(40)- 大型应用程序的项目拆分

简介: FastAPI(40)- 大型应用程序的项目拆分

背景


  • 假设要搭建一个测试平台,那么整个项目的 API 数量肯定很多个,他们不可能放在同一个文件中
  • FastAPI 提供了一个方便的工具来构建应用程序,同时保持所有的灵活性

 

项目架构


假设结构如下

.
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │   ├── __init__.py
│   │   ├── items.py
│   │   └── users.py
│   └── internal
│       ├── __init__.py
│       └── admin.py


  • main:应用程序的主入口,会添加所有子路由
  • dependencies:存放应用程序要用到的依赖项
  • routers:子路由,根据模块划分,比如 users 存放用户信息相关的路由,items 存放其他内容的路由
  • internal:一些公共路由

 

APIRouter


有点像 Flask 里面的蓝图,为某个模块创建路径操作

image.png


users.py 代码


#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/28 7:26 下午
# file: users.py
"""
from fastapi import APIRouter, Depends, HTTPException
from dependencies import get_token_header
# 属于该模块的路由
user_router = APIRouter(
    # 这里配置的 tags、dependencies、responses 对这个模块的内的所有路径操作都生效
    # 路径前缀,该模块下所有路径操作的前缀
    prefix="/users",
    # 标签
    tags=["users"],
    # 依赖项
    dependencies=[Depends(get_token_header)],
    # 响应
    responses={404: {"description": "users Not found"}}
)
@user_router.get('/account/login')
async def login():
    return {}
@user_router.get('/account/logout')
async def logout():
    return {}
# 单独给某个路径操作声明 tags、responses
@user_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"}


items.py 代码


#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/28 7:26 下午
# file: items.py
"""
from fastapi import APIRouter, Depends
from dependencies import get_token_header
item_router = APIRouter(
    # 这里配置的 tags、dependencies、responses 对这个模块的内的所有路径操作都生效
    # 路径前缀,该模块下所有路径操作的前缀
    prefix="/items",
    # 标签
    tags=["items"],
    # 依赖项
    dependencies=[Depends(get_token_header)],
    # 响应
    responses={404: {"description": "items Not found"}}
)
@item_router.get('/item')
async def index():
    return {}
@item_router.get('/item/list')
async def list():
    return {}

routers/__init__.py


from .items import item_router

from .users import user_router

 

admin.py


#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/28 7:26 下午
# file: admin.py
"""
from fastapi import APIRouter
admin_router = APIRouter()
@admin_router.post("/")
async def update_admin():
    return {"message": "Admin getting schwifty"}


common/__init__.py


from .admin import admin_router

 

main.py


#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/28 7:25 下午
# file: main.py
"""
import uvicorn
from fastapi import FastAPI, Depends
# 导入子路由
from dependencies import get_query_token, get_token_header
from routers import user_router, item_router
from common import admin_router
# 主路由
app = FastAPI(
    # 声明全局依赖项
    # 如果每个 APIRouter 都会用到这个依赖项,那么应该声明为全局依赖项
    dependencies=[Depends(get_query_token)]
)
# 添加子路由
app.include_router(user_router)
app.include_router(item_router)
# 也可以在这里给子路由声明 prefix、tags、dependencies、responses,而无需修改原始的 APIRouter
app.include_router(
    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__":
    uvicorn.run(app="main:app", host="127.0.0.1", port=8080, debug=True, reload=True)


重点

  • 使用 app.include_router() 可以将每个 APIRouter 添加到主 FastAPI 应用程序中,它将包括来自该路由器的所有路由作为它的一部分
  • 它实际上会在内部为 APIRouter 中声明的每个路径操作创建一个路径操作,因此,在幕后,它实际上会像所有东西都是同一个应用程序一样工作
  • 使用 app.include_router() 时,不必担心性能,只需要几微秒,并且只会在启动时发生,所以不会影响性能

 

主程序-子路由的架构图


image.png

  • 这个架构还是比较简单的,主程序直接包含子路由
  • 但其实子路由还可以再包含一个子路由
  • 个人把主程序也称为主路由(感觉更好理解)


user_router = APIRouter(
    prefix="/users",
)
user_router.include_router(
    router=item_router
    prefix="/items"
)


FastAPI() 的 include_router() 源码


image.png


相关文章
|
3月前
|
存储 JSON 数据安全/隐私保护
"FastAPI身份验证与授权的奥秘:如何用Python打造坚不可摧的Web应用,让你的项目一鸣惊人?"
【8月更文挑战第31天】在现代Web开发中,保证应用安全性至关重要,FastAPI作为高性能Python框架,提供了多种身份验证与授权方式,包括HTTP基础认证、OAuth2及JWT。本文将对比这些机制并附上示例代码,展示如何使用HTTP基础认证、OAuth2协议以及JWT进行用户身份验证,确保只有合法用户才能访问受保护资源。通过具体示例,读者可以了解如何在FastAPI项目中实施这些安全措施。
140 1
|
3月前
|
开发框架 JSON API
Python中FastAPI项目使用 Annotated的参数设计
Python中FastAPI项目使用 Annotated的参数设计
|
3月前
|
存储 测试技术 开发者
FastAPI异步处理的神奇之处:如何用Python打造高性能Web应用,让你的项目一鸣惊人?
【8月更文挑战第31天】在现代Web开发中,高性能至关重要。FastAPI作为一款高性能Python Web框架,支持多种异步处理方式,包括非阻塞I/O、异步函数(async/await)及异步上下文管理器(async with),能够大幅提升应用性能。本文通过示例代码详细介绍了FastAPI中的异步处理方法,并分享了最佳实践,帮助开发者构建高效的Web应用。
157 0
|
3月前
|
Java API Python
Python 搭建 FastAPI 项目
Python 搭建 FastAPI 项目
54 0
|
6月前
|
人工智能 移动开发 小程序
uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
324 2
|
NoSQL 测试技术 Redis
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
|
存储 测试技术 数据安全/隐私保护
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
|
测试技术 数据安全/隐私保护
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
|
NoSQL Redis 数据库
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞