Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseModel with simple __root__ type not allowed in Path and Query params #1437

Closed
ghost opened this issue May 20, 2020 · 5 comments
Closed
Labels
question Question or problem question-migrate

Comments

@ghost
Copy link

ghost commented May 20, 2020

Describe the bug

I want to extract enums from model schema to separate definition, and the solution is:

from enum import Enum

from pydantic import BaseModel
from devtools import debug

class HelloType(str, Enum):
    World = 'World',
    Friend = 'Friend',

class HelloEnum(BaseModel):
    __root__: HelloType

class Foo(BaseModel):
    bar: HelloEnum

debug(HelloEnum.schema())
debug(Foo.schema())

Output:

./main.py <module>
    HelloEnum.schema(): {
        'title': 'HelloEnum',
        'enum': [
            'World',
            'Friend',
        ],
        'type': 'string',
    } (dict) len=3
./main.py <module>
    Foo.schema(): {
        'title': 'Foo',
        'type': 'object',
        'properties': {
            'bar': {
                '$ref': '#/definitions/HelloEnum',
            },
        },
        'required': ['bar'],
        'definitions': {
            'HelloEnum': {
                'title': 'HelloEnum',
                'enum': [
                    'World',
                    'Friend',
                ],
                'type': 'string',
            },
        },
    } (dict) len=5

But I can't use HelloEnum in Query parameters:

@app.get('/')
async def root(hello_type: HelloEnum = Query(...)):
    return {'message': f'Hello {hello_type}'}

And I get the error:

File "./main.py", line 28, in <module>
    async def root(hello_type: HelloEnum = Query(...)):
  File "<..>/python3.8/site-packages/fastapi/routing.py", line 514, in decorator
    self.add_api_route(
  File "<..>/python3.8/site-packages/fastapi/routing.py", line 453, in add_api_route
    route = route_class(
  File "<..>/python3.8/site-packages/fastapi/routing.py", line 370, in __init__
    self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
  File "<..>/python3.8/site-packages/fastapi/dependencies/utils.py", line 308, in get_dependant
    assert isinstance(
AssertionError: Param: hello_type can only be a request body, using Body(...)

To Reproduce

  1. Create a file with:
from enum import Enum

from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()


class HelloType(str, Enum):
    World = 'World',
    Friend = 'Friend',


class HelloEnum(BaseModel):
    __root__: HelloType

@app.get('/')
async def root(hello_type: HelloEnum = Query(...)):
    return {'message': f'Hello {hello_type}'}
  1. Run app.
  2. It trows an exception AssertionError: Param: hello_type can only be a request body, using Body(...).
  3. But I expected it to run successfully.

Expected behavior

Run app successfully, and in openapi schema enum extracted in the separate definition.

Environment

  • macOS 10.15.4
  • FastAPI 0.54.2
  • Python 3.8.2
@ghost ghost added the bug Something isn't working label May 20, 2020
@phy25
Copy link

phy25 commented May 20, 2020

Do you think it's a duplicate of #911?

@ghost
Copy link
Author

ghost commented May 20, 2020

Partially. In this case, I am trying to extract the enum in the schema definitions. This useful for openapi-generator, otherwise it generates separate enums (e.g. for typescript).

@espdev
Copy link

espdev commented Mar 2, 2021

I have a similar issue. And I try to use request body instead but that raises an error too.

For example:

class QueryDict(BaseModel):
    __root__: dict[str, str]
    
    # some validators here
    ...

class Query(BaseModel):
    query: QueryDict

@app.post('/foo')
def foo(query: Query):
    ...

Request:

curl -X POST "http://127.0.0.1:8888/foo" -H  "accept: application/json" -H  "Content-Type: application/json" -d '{"query":{"hello":"world"}}'

In this case I get a validation error:

{
  "detail": [
    {
      "loc": [
        "body",
        "query",
        "__root__"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

#911/#1524 does not fix this.

@tiangolo do you have any thoughts on this?

It seems to me this is a pydantic issue.

Query.parse_obj({"query":{"hello":"world"}})

ValidationError: 1 validation error for Query
query -> __root__
  field required (type=value_error.missing)

pydantic/pydantic#2100

Also nested __root__ parse was fixed in pydantic v1.8 but Query still cannot be custom __root__ model in fastapi.

@tiangolo
Copy link
Owner

Pydantic models are not supported for other things apart from bodies. I want to add a way to support them for query parameters and others, but that's not supported yet.

Sorry for the long delay! 🙈 I wanted to personally address each issue/PR and they piled up through time, but now I'm checking each one in order.

@tiangolo tiangolo changed the title [BUG] BaseModel with simple __root__ type not allowed in Path and Query params BaseModel with simple __root__ type not allowed in Path and Query params Nov 14, 2022
@tiangolo tiangolo added question Question or problem answered and removed bug Something isn't working labels Nov 14, 2022
@github-actions
Copy link
Contributor

Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.

@tiangolo tiangolo reopened this Feb 28, 2023
@github-actions github-actions bot removed the answered label Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #7419 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

3 participants