Skip to content
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

Union produces anyOf instead of oneOf for OpenAPI generation #4125

Closed
3 tasks done
stdkoehler opened this issue Jun 1, 2022 · 1 comment · Fixed by #4335
Closed
3 tasks done

Union produces anyOf instead of oneOf for OpenAPI generation #4125

stdkoehler opened this issue Jun 1, 2022 · 1 comment · Fixed by #4335
Labels
bug V1 Bug related to Pydantic V1.X

Comments

@stdkoehler
Copy link

stdkoehler commented Jun 1, 2022

Checks

  • I added a descriptive title to this issue
  • I have searched (google, github) for similar issues and couldn't find anything
  • I have read and followed the docs and still think this is a bug

Bug

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.9.0
            pydantic compiled: True
                 install path: C:\Users\DEKOEHLS\Programme\Anaconda3\Lib\site-packages\pydantic
               python version: 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)]
                     platform: Windows-10-10.0.19042-SP0
     optional deps. installed: ['dotenv', 'typing-extensions']
from typing import Literal, Union
from pydantic import BaseModel, Field


class Cat(BaseModel):
    pet_type: Literal['cat']
    meows: int


class Dog(BaseModel):
    pet_type: Literal['dog']
    barks: float


class Pet(BaseModel):
    __root__: Union[Cat, Dog] = Field(..., discriminator='pet_type')

Pet.schema_json()

Hi all,

Example from https://pydantic-docs.helpmanual.io/usage/types/#discriminated-unions-aka-tagged-unions:

Using the class Pet above in FastAPI to allow either Cat or Dog as an input leads to an OpenAPI.json which makes Pet like (printed as yaml)

Pet:
  anyOf:
  - $ref: '#/components/schemas/Cat'
  - $ref: '#/components/schemas/Dog'
  
  discriminator:
    propertyName: pet_type

both OpenApi (https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/) and the specification https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#discriminatorObject linked by the pydantic docs (link on top) state that it should be oneOf.
This also corresponds to the "typing" interpretation of Union which is, besides the naming, not a union of the arguments but a "one of those elements"

I already found a issue here which has been closed:
#656
I didn't understand the arguments to be honest, However, I think it's just wrong to make it an anyOf.

I tried to post it on FastAPI since it leads to an incorrect openapi.json so I thought maybe a workaround on FastAPI side was meaningful. They forwarded me back here though.
tiangolo/fastapi#4959

Best
Stefan

@stdkoehler stdkoehler added the bug V1 Bug related to Pydantic V1.X label Jun 1, 2022
@MaxwellPayne
Copy link
Contributor

I agree that this is a bug. I ran into an issue when using openapi-generator to generate a TypeScript SDK from an anyOf discriminated union that was generated by Pydantic. The generated TypeScript code looked incorrect when my models used anyOf, but worked just fine once I switched to oneOf.

I opened #4335 to propose a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V1 Bug related to Pydantic V1.X
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants