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

Is it possible to have multiple body schemas? #432

Closed
jonDel opened this issue Aug 12, 2019 · 10 comments
Closed

Is it possible to have multiple body schemas? #432

jonDel opened this issue Aug 12, 2019 · 10 comments
Labels
question Question or problem question-migrate

Comments

@jonDel
Copy link

jonDel commented Aug 12, 2019

Description

In a Response, according to the documentation, I can have a Union of multiple pydantic models as the response of an endpoint operation. That works fine. However, it seems that there is no way to use a similar approach when receiving input in a a body. My problem: I have an endpoint, and this endpoint could receive any of 4 different models as valid input in the body. I tried to define a Union, and it breaks the fastapi schema generation; I tried to use Any, from pydantic, and fastapi treats the input as a query operation instead of a body operation (the same happens if I don't use any model at all)

Consider Foobar, Model1 and Model2 as pydantic classes.

The following breaks schema generation:

@router.post("/{foobar}")
def post_foobar(foobar: Foobar, bar: Union[Model1, Model2], response: Response):

The following makes fastapi understand bar as a query:

@router.post("/{foobar}")
def post_foobar(foobar: Foobar, bar: Any, response: Response):

The following makes fastapi understand bar as a query either:

@router.post("/{foobar}")
def post_foobar(foobar: Foobar, bar, response: Response):

Is there a way to fix this behavior? Or simply force fastapi to understand "bar" as body and NOT a query parameter?

@jonDel jonDel added the question Question or problem label Aug 12, 2019
@jonDel jonDel changed the title [QUESTION] It is possible to have multiple body schemas? [QUESTION] Is it possible to have multiple body schemas? Aug 12, 2019
@inikolaev
Copy link

I'm also interested in support of union types in requests.

In my use-case a model has an attribute type, which could be used to figure out which class to instantiate, e.g.:

class Bicycle(BaseModel):
  # attributes specific for bicycle here
  type: str = 'bicycle'

class Car(BaseModel):
  # attributes specific for car here
  type: str = 'car'

class MyRequest(BaseModel):
  vehicle: Union[Bicycle, Car]

In there example above I would like vehicle to an instance of the Car or Bicycle, depending on the value of type attribute received in JSON:

{
  "vehicle": {
    "type": "bicycle",
    "break_type": "hydraulic"
  }
}

@inikolaev
Copy link

As I understand it depends on pydantic and I found the following ticket there: pydantic/pydantic#619

@tiangolo
Copy link
Owner

Thanks for the discussion here @inikolaev .

@jonDel maybe it was a bug at some point and it was fixed in recent versions, because this seems to work:

from fastapi import FastAPI
from typing import Union
from pydantic import BaseModel


class User(BaseModel):
    name: str


class Item(BaseModel):
    size: int
    price: float


app = FastAPI()


@app.post("/multi/")
def process_things(body: Union[User, Item]):
    return body

Still, if you want to have single fields (Any, str, etc) as bodies, check the docs: https://fastapi.tiangolo.com/tutorial/body-fields/

@github-actions
Copy link
Contributor

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

@mcauto
Copy link

mcauto commented May 15, 2020

Thanks for the discussion here @inikolaev .

@jonDel maybe it was a bug at some point and it was fixed in recent versions, because this seems to work:

from fastapi import FastAPI
from typing import Union
from pydantic import BaseModel


class User(BaseModel):
    name: str


class Item(BaseModel):
    size: int
    price: float


app = FastAPI()


@app.post("/multi/")
def process_things(body: Union[User, Item]):
    return body

Still, if you want to have single fields (Any, str, etc) as bodies, check the docs: https://fastapi.tiangolo.com/tutorial/body-fields/

It's works!

but sample request body is empty in swagger

How to set default request body?

image

@phy25
Copy link

phy25 commented May 17, 2020

@mcauto See #1083.

@ritikjain51
Copy link

I have tried the approach. Dynamic schema detection is not happening here.

The current approach is working with basic datatypes like int, float and all but user-defined structures or pydantic models not working. It is considering the object in basic datatype like dict or list.

Thanks in advance

@jammymalina
Copy link

I have tried the approach. Dynamic schema detection is not happening here.

The current approach is working with basic datatypes like int, float and all but user-defined structures or pydantic models not working. It is considering the object in basic datatype like dict or list.

Thanks in advance

I am facing the same issue. Is there already a github issue for this open?

@JarroVGIT
Copy link
Contributor

What is the issue then? Because the solution given above works with regard the original issue.

image

@jammymalina
Copy link

jammymalina commented Sep 14, 2022

I am getting 422 Unprocessable Entity error. Strangely it works fine in the unit test. Let me check it again though, if I don't get back to you then it works fine.

EDIT: Sorry for the created confusion, it seems the input data changed a little - the body was not passing validation. Everything is working as expected once I updated the schema.

@tiangolo tiangolo changed the title [QUESTION] Is it possible to have multiple body schemas? Is it possible to have multiple body schemas? Feb 24, 2023
@tiangolo tiangolo reopened this Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #8211 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

8 participants