如何将body读作任何有效的json?

bttbmeg0  于 2023-01-22  发布在  其他
关注(0)|答案(7)|浏览(157)

我还没有找到这个用例的文档。我如何获得请求主体,确保它是一个有效的JSON(任何有效的JSON,包括数字、字符串、布尔值和空值,而不仅仅是对象和数组),并获得实际的JSON。使用Pydantic强制JSON具有特定的结构。

muk1a3rh

muk1a3rh1#

几乎可以找到Request对象中的所有内容
您可以使用request.json()获取请求主体,它将给予解析后的JSON作为字典。

from fastapi import Request, FastAPI

@app.post("/dummypath")
async def get_body(request: Request):
    return await request.json()

如果要以字符串形式访问主体,可以使用request.body()

ufj5ltwl

ufj5ltwl2#

接受的answer也是有效的,但FastAPI提供了一种内置的方法来实现这一点-检查文档中主体部分的奇异值。
默认值为Body的参数获取所有与传递的Pydant类型参数不匹配的有效负载(在我们的例子中是整个有效负载),并将其转换为dict。

from fastapi import Body, FastAPI

app = FastAPI()

@app.post('/test')
async def update_item(
        payload: dict = Body(...)
):
    return payload

UPD:...(省略号)的注解-它允许根据需要标记值。更多信息请参阅省略号文档中的必需部分

laik7k3q

laik7k3q3#

  • 如果您确信传入的数据是**"一个有效的JSON"***,则可以创建一个简单的 * type annotation * 结构来接收任意JSON数据。
from fastapi import FastAPI
from typing import Any, Dict, AnyStr, List, Union

app = FastAPI()

JSONObject = Dict[AnyStr, Any]
JSONArray = List[Any]
JSONStructure = Union[JSONArray, JSONObject]

@app.post("/")
async def root(arbitrary_json: JSONStructure = None):
    return {"received_data": arbitrary_json}

示例

      1. JSON对象**
curl -X POST "http://0.0.0.0:6022/" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"test_key\":\"test_val\"}"

回复:

{
  "received_data": {
    "test_key": "test_val"
  }
}
      1. JSON数组**
curl -X POST "http://0.0.0.0:6022/" -H  "accept: application/json" -H  "Content-Type: application/json" -d "[\"foo\",\"bar\"]"

回复:

{
  "received_data": [
    "foo",
    "bar"
  ]
}

如果您不确定传入数据的 * 内容类型 *,最好解析 * 请求正文 *。
它可以被实现为,

from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/")
async def root(request: Request):
    return {"received_request_body": await request.body()}

这种方法的优点是主体可以包含任何类型的数据,JSON、表单数据、多部分表单数据等等。

wrrgggsh

wrrgggsh4#

from fastapi import Request

async def synonyms__select(request: Request):
    return await request.json()

将返回JSON对象。

epfja78i

epfja78i5#

这是一个打印Request内容的例子,它将打印json主体(如果它是json可解析的),否则只打印主体的原始字节。

async def print_request(request):
        print(f'request header       : {dict(request.headers.items())}' )
        print(f'request query params : {dict(request.query_params.items())}')  
        try : 
            print(f'request json         : {await request.json()}')
        except Exception as err:
            # could not parse json
            print(f'request body         : {await request.body()}')
    
    
    @app.post("/printREQUEST")
    async def create_file(request: Request):
        try:
            await print_request(request)
            return {"status": "OK"}
        except Exception as err:
            logging.error(f'could not print REQUEST: {err}')
            return {"status": "ERR"}
ar5n3qh5

ar5n3qh56#

FastAPI有一个JSON encoder
在某些情况下,您可能需要将数据类型(如Pydantic模型)转换为与JSON兼容的类型

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
import simplejson as json

class SubmitGeneral(BaseModel):
    controllerIPaddress: str
    readerIPaddress: str
    ntpServer: str

@app.post("/submitGeneral")
async def submitGeneral(data: SubmitGeneral):
    data = jsonable_encoder(data)
    #data = json.loads(data.json()) # same as above line
    
    print(f"data = {json.dumps(data)}")

    # you have to access the properties with brackets, not by dot notation
    query = f"update LocalPLC set ControllerIpAddress = '{data['controllerIPaddress']}', ReaderIPAddress = '{data['readerIPaddress']}'"

    return {"status": "OK"}
cgfeq70w

cgfeq70w7#

对于使用BaseModel并希望拥有JSON字段的用户,可以从pydantic导入JSON

from fastapi import FastAPI
from pydantic import BaseModel, Json, Field

app = FastAPI()

class MockEndpoint(BaseModel):
    endpoint: str = Field(description="API endpoint to mock")
    response: Json = Field(description="Example response of the endpoint")

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.post("/mock")
async def mock_request(mock_endpoint: MockEndpoint):
    return mock_endpoint

相关问题