测试开发框架 FastAPI 如何编写接口

发布于 更新于
本文目录
  1. url 路径参数
  2. 查询字符串参数(query string)
  3. 获取 header
  4. 获取 form 表单数据
  5. 获取 body
  6. 关于参数的其他说明
  7. 直接使用 request 对象
  8. 默认返回 json
  9. 状态码和响应 Header
  10. 返回 HTML
  11. 返回文件
  12. 返回视频

技术文章测试开发

请求处理和返回响应是任何一个开发框架最核心的内容。这篇文章主要讲 FastAPI 中如何处理用户的请求参数和响应。

请求处理和返回响应是任何一个开发框架最核心的内容。这篇文章主要讲 FastAPI 中如何处理用户的请求参数和响应。

url 路径参数

URL 路径参数指的是通过在 URL 的斜杠后面传递的参数。比如我们要访问 id 为 2 的 project, 则可以访问 /project/2 这个 URL。

但是这个 2 是每次都会变的,被称为 URL 路径参数。

在 FastAPI 中,用花括号 {id} 表示动态变化的 URL 参数, 然后在函数中,通过同名的 id 作为参数接收。


@app.get('/project/{id}')

def project(id):

    return id

查询字符串参数(query string)

和 路径参数类似,你也可以通过查询字符串的形式传递 id。 查询字符串就是在 url 中通过 ? 号后面加参数。 比如 /project/?id=2 这种形式。

使用上和路径参数差不多,也是通过 id 传递到函数当中。 当找不到路径参数时,会在 query string 中查询字段。


# query string

@app.get('/project/')

def project(id):

    return id

获取 header

有时候在请求中需要获取 header 当中的数据,比如在请求中经常会在 Authorization 中获取 token 值。

则可以在视图函数中添加 authorization=Header(None) 的关键字参数,表示通过 authorization 变量获取 header 中的 Authorization 字段值。

注意参数名一定要和 header 中字段的名称一致。


from fastapi import Header


@app.get('/project/')

def project(authorization=Header(None)):

    return authorization

获取 form 表单数据

有时候在请求中需要获取 form 表单当中的数据,比如用户传过来的用户名和密码。

则可以通过 username 和 password 分别接受 form 表单中的用户名和密码。变量名同样和传入的数据字段保持一致。


from fastapi import Form


@app.get('/project/')

def project(username=Form(None), password=Form(None)):

    return username

获取 body

获取 body 和 header 类似,不同的是变量获取的是所有 body 数据字段,而不是和 header 那样,必须填入指定的参数名。

比如可以通过 item = Body(None) item 变量接收所有 body 数据。

需要注意的是:FastAPI 中 Body() 对象接收的是 json 格式数据, 如果想接收表单类型数据,需要通过 Form()


@app.post('/login/')

def project(user = Body(None)):

    return user

假设在请求中传递了 json 数据:


{

    "username": "yuz",

    "pwd": 123

}

则该接口中 user 可以获取到以上数据。

关于参数的其他说明

FastAPI 给每种参数类型都定义了对应的对象:

  • Path

  • Query

  • Body

  • Form

  • File

其实,获取路径参数可以这样:


@app.get('/project/{id}')

def project(id=Path(...)):

    return id

获取 query string 可以是这样:


@app.get('/project/{id}')

def project(id=Query(...)):

    return id

注意:header,query, path 都必须要有对应的字段才能读取到,但是 Body 是把所有的字段都读取出来。

直接使用 request 对象


@app.get("/items/{item_id}")

def read_root(item_id: str, request: Request):

    client_host = request.client.host

    return {"client_host": client_host, "item_id": item_id}

使用 request 对象获取请求对象非常方便。当时获取 form 表单这样的数据只能调用 request.form() 方法,

这里得到的是一个协程对象。所以需要采用异步方式处理:


async def user(req: Request):

    user = await req.form()

或者使用 asyncio 运行


def user(req: Request):

    user = asyncio.run(req.form())

要直接获取 form 表单,也可以直接用 Form 对象。

默认返回 json

直接返回字典或者列表


@app.get('/project/')

def project():

    return {"msg": "projects"}

状态码和响应 Header


def project():

    return JSONResponse(

        {"msg": "hello"},

        status_code=200,

        headers={'you': 'ok'}

    )

返回 HTML


def project():

    content = """

    <html>

        <h1 style="color:red">hello world</h1>

    </html>

    """

    return HTMLResponse(content)

返回文件

读取文件一定要先安装一个库 aiofile。


pip install aiofiles

然后使用 FileResponse


def project():

    return FileResponse('yy.jpg')

或者直接下载文件:


def project():

    return FileResponse('文件路径.xls', filename='下载的文件.xls')

返回视频


def file():

    file = open("demo.mp4", 'rb')

    return StreamingResponse(file, media_type='video/mp4')

但是这个会一次性读取视频,如果很大,加载速度会很慢:

image.png

最好的方式是通过生成器一次返回指定大小的数据:


def get_video(file):

    with open(file, 'rb') as f:

        while True:

            chuck = f.read(5000)

            if chuck:

                yield chuck

            else:

                break


def file():

    return StreamingResponse(

        get_video('抖音拍摄-吃苹果-花絮1.mp4'),

        media_type='video/mp4'

        )

来源:testingpai

继续阅读