sqlalchemy fastapi 官方应用示例
static 文件
模板 templates
大型应用项目结构
第三方脚手架工具

sqlalchemy fastapi应用示例

  1. 项目文件结构
$ cd /offical_fastapi_project
$ tree .
.
├── README.md
├── sql_app
│   ├── __init__.py
│   ├── crud.py   # 数据库数据的增删改查
│   ├── database.py   # 数据库相关配置(创建引擎,创建SessionLocal,创建用于orm模型继承的Base类)
│   ├── main.py # 定义FastAPI app及相关api接口,注意其中的Depends db session(实例化的SessionLocal)
│   ├── models.py  #  SQLAlchemy models,继承自Base类的表类
│   └── schemas.py  #  Pydantic models,基于BaseModel
└── sql_app.db
  1. 数据库相关配置
  2. database models
  3. pydantic models
  4. CRUD utils
  5. fastapi app
  6. database migrations

运行项目uvicorn sql_app.main:app --reload

Static Files

在项目中,如果需要使用到静态文件,可使用 StaticFiles 挂载(mount)到应用程序中

  • 挂载:将一个完全独立的指定路径下的应用(StaticFiles实例)添加进来
# app.mount 源码:
def mount(self, path: str, app: ASGIApp, name: str = None) -> None:
    self.router.mount(path, app=app, name=name)
  • 示例
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
import uvicorn

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
  1. /static:是指这个“子应用”将被mount到的子路径
  2. directory="static"是指包含static文件的目录名
  3. name="static"是可以被FastAPI内部使用的名称
  4. 因此所有这些参数可任意命名,不必一定为static
    如将图片"monkeyjerry.png"放在static目录下,通过浏览器访问http://127.0.0.1:8000/static/monkeyjerry.png将可展示对应的图片

模板 templates

在之前的文章模板引擎Jinja2有过介绍,这里就不再赘述
几点注意:

  1. 在路径操作中声明一个Request参数,这个函数返回TemplateResponse
  2. 将request作为kv对参数传入jinja2的context中来呈现你创建的template
  3. jinja模板引擎语法
  4. 在模板中使用url_for()来引用静态文件

大型应用/多个应用

如果用过Flask,这将类似于Flask的Blueprints

  1. 项目文件结构
.
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │   ├── __init__.py
│   │   ├── items.py
│   │   └── users.py
│   └── internal
│       ├── __init__.py
│       └── admin.py
  1. 处理用户的模块user.py
  • 使用APIRouter为模块创建路径操作
    • 可以将 APIRouter 视为一个迷你的 FastAPI 类,所有相同的选项都得到支持,所有相同的 parameters、responses、dependencies、tags 等等
from fastapi import APIRouter

router = APIRouter()

@router.get("/users/", tags=["users"])
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]
...
...
  1. 依赖项dependencies.py供其他地方使用
  2. 另外的处理item的的模块items.py
  • 同样使用到APIRouter,可在APIRouter中添加参数(将影响到每个路径操作)
    • prefix:路径 prefix,每个路径操作中添加前缀
    • tags:标签
    • dependencies:这些依赖项将被添加到路由器中的所有路径操作中
    • responses:所有的路径操作都将包含预定义的 responses
  • 也可在特定的路径操作添加tags(这个路径操作将包含标签的组合)和额外responses
  1. fastapi main.py
  • app = FastAPI(dependencies=[Depends(get_query_token)])声明全局依赖项
  • 使用 app.include_router(),可以将每个 APIRouter 添加到主 FastAPI 应用程序中
    • 可以在app.include_router()中来声明prefix、dependencies、tags 等(假设由于它是与组织中的其他项目所共享的,因此我们无法对其进行修改,以及直接在 APIRouter 中添加 prefix、dependencies、tags 等)
    • 可以在同一路由器上使用不同的前缀来多次使用 .include_router()
    • 可以在另一个 APIRouter 中包含 APIRouter,通过router.include_router(other_router)

脚手架

如果用过Django,我们都知道可以使用django-admin startapp name [directory]在当前目录或给定directory的目录中为给定的应用名name创建一个 Django 应用目录结构
很可惜,fastapi 官方并没有提供类似这样的命令行工具,这里收集了几个第三方的,仅供参考:

Manage FastAPI

pip install manage-fastapi 
  • help说明
$  fastapi --help
Usage: fastapi [OPTIONS] COMMAND [ARGS]...

  Managing FastAPI projects made easy!

Options:
  --version  Show the Manage FastAPI version information.
  --help     Show this message and exit.

Commands:
  run           Run a FastAPI application.
  startapp      Creates a FastAPI component.
  startproject  Creates a FastAPI project.
$ fastapi startproject --help
Usage: fastapi startproject [OPTIONS] NAME

  Creates a FastAPI project.

Arguments:
  NAME  [required]

Options:
  --interactive / --no-interactive
                                  Run in interactive mode.  [default: False]
  --database [Postgres|MySQL]
  --docker / --no-docker          [default: False]
  --license [MIT|BSD|GNU|Apache]
  --packaging [pip|poetry]        [default: pip]
  --pre-commit                    [default: False]
  --python [3.6|3.7|3.8|3.9]      [default: 3.8]
  --help                          Show this message and exit.

参考及扩展阅读