FastAPI Concise Tutorial

Request processing and returning responses are the core content of any development framework. This article mainly talks about how to handle user's request parameters and responses in FastAPI.

url path parameter

URL path parameters refer to parameters passed after the slash in the URL. For example, if we want to access the project whose id is 2, we can access the URL /project/2.

But this 2 changes every time and is called the URL path parameter.

In FastAPI, a dynamically changing URL parameter is represented by curly braces {id}, and then in the function, the id of the same name is received as a parameter.

  

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

def project(id):

    return id
复制代码

query string parameters

Similar to path parameters, you can also pass the id as a query string. The query string is to add parameters after the ? sign in the url. For example /project/?id=2 this form.

The usage is similar to the path parameter, and it is also passed to the function through the id. When no path parameter is found, the field is queried in the query string.

  

# query string

@app.get('/project/')

def project(id):

    return id
复制代码

get header

Sometimes the data in the header needs to be obtained in the request, for example, the token value is often obtained in the Authorization in the request.

Then you can add authorization=Header(None)the , indicating that the Authorization field value in the header is obtained through the authorization variable.

Note that the parameter name must be the same as the field name in the header.

  

from fastapi import Header


@app.get('/project/')

def project(authorization=Header(None)):

    return authorization
复制代码

Get form form data

Sometimes it is necessary to obtain the data in the form in the request, such as the user name and password passed by the user.

Then you can accept the username and password in the form through username and password respectively. The variable name is also consistent with the incoming data field.

  

from fastapi import Form


@app.get('/project/')

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

    return username
复制代码

get body

Getting the body is similar to the header, the difference is that the variable gets all the body data fields, instead of the header, the specified parameter name must be filled in.

For example item = Body(None), all body data can be received through the item variable.

需要注意的是: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

728 x 220 830 x 251

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

  

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'

        )
复制代码

Guess you like

Origin juejin.im/post/7086789422233944077