Skip to content

Using pydantic Json Type as Form data type doesn't work #10997

@Kludex

Description

@Kludex

Discussed in #9305

Originally posted by harpaj March 23, 2023

First Check

  • I added a very descriptive title here.
  • I used the GitHub search to find a similar question and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from typing import Annotated

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

app = FastAPI()


class JsonListModel(BaseModel):
    json_list: Json[list[str]]


@app.post("/working")
async def working(json_list: Annotated[str, Form()]) -> list[str]:
    model = JsonListModel(json_list=json_list)
    return model.json_list


@app.post("/broken")
async def broken(json_list: Annotated[Json[list[str]], Form()] ) -> list[str]:
    return json_list

Description

In the example code above, I would expect working and broken to be approximately equivalent.
However, while working returns the parsed json_list as expected, broken fails with

{"detail":[{"loc":["body","json_list"],"msg":"JSON object must be str, bytes or bytearray","type":"type_error.json"}]}

Operating System

Linux

Operating System Details

No response

FastAPI Version

0.95.0

Python Version

Python 3.10.8

Additional Context

sample request that fails with broken and works with working:

import requests
import json

headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.post(
    "http://0.0.0.0:8000/broken",
    data={"json_list": json.dumps(["abc", "def"])},
    headers=headers,
)
```</div>

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionQuestion or problem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions