首页 > 后端开发 > Python教程 > 如何创建接受表单或 JSON 正文的 FastAPI 端点?

如何创建接受表单或 JSON 正文的 FastAPI 端点?

DDD
发布: 2024-10-27 06:16:03
原创
606 人浏览过

How to Create a FastAPI Endpoint That Accepts Either Form or JSON Body?

如何创建可以接受 Form 或 JSON body 的 FastAPI 端点?

在 FastAPI 中,您可以定义处理各种类型请求正文的端点,例如JSON 或表单数据。这允许您创建可以接受任一格式的端点,而无需单独的端点。

要实现此目的,您可以遵循以下方法之一:

选项 1:使用依赖函数

您可以利用依赖函数来验证请求的 Content-Type 标头,然后使用 Starlette 的方法适当地解析正文。请注意,仅依赖 Content-Type 标头可能无法始终保证请求正文的有效性,因此建议包含错误处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<code class="python">import os, sys

from fastapi import FastAPI, Depends, HTTPException

from starlette.requests import Request

app = FastAPI()

 

# Generating file

open("./app.txt", "w").write("hello from a file")

 

async def body_parser(request: Request):

    ct = request.headers.get("Content-Type", "")

    if ct == "application/json":

        try:

            d = await request.json()

            if not isinstance(d, dict):

                raise HTTPException(status_code=400, details={"error":"request body must be a dict"})

            return d

        except JSONDecodeError:

            raise HTTPException(400, "Could not parse request body as JSON")

    elif ct == "multipart/form-data":

        await request.stream()  # this is required for body parsing.

        d = await request.form()

        if not d:

            raise HTTPException(status_code=400, details={"error":"no form parameters found"})

        return d

    else:

        raise HTTPException(405, "Content-Type must be either JSON or multipart/form-data")

 

@app.post("/", dependencies=[Depends(body_parser)])

async def body_handler(d: dict):

    if "file" in d:

        return {"file": d["file"]}

    return d</code>

登录后复制

选项 2:利用可选表单/文件参数

在此方法中,您可以在端点中将表单/文件参数定义为可选。如果这些参数中的任何一个具有值,则它假定是表单数据请求。否则,它将验证请求正文为 JSON。

1

2

3

4

5

6

7

8

9

10

11

<code class="python">from fastapi import FastAPI, Form, File, UploadFile

app = FastAPI()

 

@app.post("/")

async def file_or_json(

    files: List[UploadFile] = File(None),

    some_data: str = Form(None)

):

    if files:

        return {"files": len(files)}

    return {"data": some_data}</code>

登录后复制

选项 3:为每种类型定义单独的端点

您还可以创建单独的端点,一个用于 JSON,另一个用于表单数据。使用中间件,您可以检查 Content-Type 标头并将请求重新路由到适当的端点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<code class="python">from fastapi import FastAPI, Request, Form, File, UploadFile

from fastapi.responses import JSONResponse

app = FastAPI()

 

@app.middleware("http")

async def middleware(request: Request, call_next):

    ct = request.headers.get("Content-Type", "")

    if ct == "application/json":

        request.scope["path"] = "/json"

    elif ct in ["multipart/form-data", "application/x-www-form-urlencoded"]:

        request.scope["path"] = "/form"

    return await call_next(request)

 

@app.post("/json")

async def json_endpoint(json_data: dict):

    pass

 

@app.post("/form")

async def form_endpoint(file: UploadFile = File(...)):

    pass</code>

登录后复制

选项 4:引用另一个答案以获取替代方法

此外,您可以在 Stack Overflow 上找到这个答案很有帮助,因为它提供了在单个端点中处理 JSON 和表单数据的不同视角:

https://stackoverflow.com/a/67003163/10811840

测试选项 1、2 和 3

出于测试目的,您可以使用请求库:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<code class="python">import requests

 

url = "http://127.0.0.1:8000"

# for testing Python 3.7 and above use:

# url = "http://localhost:8000"

 

# form-data request

files = [('files', ('a.txt', open('a.txt', 'rb'), 'text/plain'))]

response = requests.post(url, files=files)

print(response.text)

 

# JSON request

data = {"some_data": "Hello, world!"}

response = requests.post(url, json=data)

print(response.text)</code>

登录后复制

这些方法提供了不同的方法来创建可以处理 JSON 和表单的端点-FastAPI 中的数据。选择最适合您的要求和用例的方法。

以上是如何创建接受表单或 JSON 正文的 FastAPI 端点?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板