Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Inconsistent behavior with basic types in parameter declarations#14412

Unanswered
wpietri asked this question inQuestions
Discussion options

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 toPydantic.
  • I already checked if it is not related to FastAPI but toSwagger UI.
  • I already checked if it is not related to FastAPI but toReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

fromtypingimportAny,Dict,List,UnionfromfastapiimportFastAPI,Bodyfromstarlette.requestsimportRequestfromstarlette.responsesimportResponseapp=FastAPI()@app.post("/any")# fails with 422asyncdefhandle(request:Any):print(f"got{request}")returnrequest@app.post("/raw")# worksasyncdefhandle(request:Request):print(f"got{request}")returnResponse(content=awaitrequest.body())@app.post("/dict")# worksasyncdefhandle(request:Dict):print(f"got{request}")returnrequest@app.post("/list")# fails with 422asyncdefhandle(request:List):print(f"got{request}")returnrequest@app.post("/anybody")# worksasyncdefhandle(request:Any=Body(None)):print(f"got{request}")returnrequest

Description

I have what I think to be a bug in FastAPI, or is at least an opportunity to make something clearer in the docs.

We are creating a service that basically proxies requests from the outside world to our existing services. Some of those services basically pass requests along to other services. We would like the outer services to have no opinion on the content that is getting passed along, such that request validation happens at the service that actually cares about the request. This reduces duplication and risk of subtle bugs.

To us the obvious way to do this was to declare a method parameter ofAny. But that doesn't work. Rummaging around, I discovered that we could, as shown in the example code, just get the body and pass it along. But that's not convenient if we want to, say, log some of the JSON. We can declare a request as as Dict and have it work, but List doesn't. And rummaging through Stack Overflow, I found that Any does work if it's done asAny = Body(None), which even after some study is still mysterious to me.

If people agree this is a bug, should I file it as an issue?

Operating System

Linux

Operating System Details

No response

FastAPI Version

0.122.0

Pydantic Version

2.12.3

Python Version

Python 3.13.5

Additional Context

No response

You must be logged in to vote

Replies: 2 comments 3 replies

Comment options

@app.post("/any")# fails with 422asyncdefhandle(request:Any):print(f"got{request}")returnrequest

That works for me, can I see how are u doing the curl?

You must be logged in to vote
3 replies
@JavierSanchezCastro
Comment options

Fromhttps://fastapi.tiangolo.com/tutorial/body/#request-body-path-query-parameters

The function parameters will be recognized as follows:

If the parameter is also declared in the path, it will be used as a path parameter.
If the parameter is of a singular type (like int, float, str, bool, etc) it will be interpreted as a query parameter.
If the parameter is declared to be of the type of a Pydantic model, it will be interpreted as a request body.

I think this is whyAny = Body(None) works

@wpietri
Comment options

@app.post("/any")# fails with 422asyncdefhandle(request:Any):print(f"got{request}")returnrequest

That works for me, can I see how are u doing the curl?

I'm not using curl, but this is the request and response:

POST http://localhost:8000/anyContent-Type: application/jsonContent-Length: 2User-Agent: IntelliJ HTTP Client/PyCharm 2025.2.4Accept-Encoding: br, deflate, gzip, x-gzipAccept: */*[]HTTP/1.1 422 Unprocessable Contentdate: Wed, 26 Nov 2025 18:08:14 GMTserver: uvicorncontent-length: 93content-type: application/json{  "detail": [    {      "type": "missing",      "loc": [        "query",        "request"      ],      "msg": "Field required",      "input": null    }  ]}
@JavierSanchezCastro
Comment options

Oh okey understood, if you go to the swagger docs, u will see that this param is interpreted by FastAPI as Query Param, since you're not sending it as Query Param ur receiving the 422 error.

If you need to passAny as value, useAny = Body() or if you know that will be a JSON you can use something like:

frompydanticimportJsonValuefromtypingimportAnnotated@app.post("/anybody")asyncdefhandle(request:Annotated[JsonValue,Body()]):print(f"got{request}")returnrequest
Comment options

Why not typing and using/passing around theRequest object directly? If you are using your app as a proxy for another app you don't necessarily need any validation

You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
questionQuestion or problem
3 participants
@wpietri@cepedus@JavierSanchezCastro

[8]ページ先頭

©2009-2025 Movatter.jp