Fastapi: Literal type with multiple elements not visible in SwaggerUI 'Example Value'[BUG]

Created on 24 Sep 2019  Â·  13Comments  Â·  Source: tiangolo/fastapi

Describe the bug
A model with a field with 'Literal' type that has multiple allowed entries does not get populated in the SwaggerUI 'Example Value'

To Reproduce
Create a Model with a Literal type that has 1 element, and another with a Literal type with multiple allowed elements.
_Example:_

class Dog(BaseModel):
    name: Literal["Fred"]
    dog: Literal["dog", "Dog"]
    pup: Literal["puppy", "pup pup", "pupper"]

Expected behavior
The fields names would be populated in the model under 'Example Value'.

Screenshots
Screen Shot 2019-09-23 at 5 40 04 PM
Screen Shot 2019-09-23 at 5 39 58 PM

Environment:

  • OS: macOS
  • python: 3.7.0
  • fastapi: 0.38.1
  • Pydantic: 0.32.2
bug

Most helpful comment

@ashears it is also possible to manually override the example shown in swagger through the schema_extra config setting on the pydantic model; this might get the string to be right for you.

All 13 comments

I created a question issue about this earlier: https://github.com/tiangolo/fastapi/issues/516 .
I closed that question and opened this bug once I noticed that the expected behavior was working inside of the schema, but not in the Example Value

This is a good question, and is actually an issue with pydantic — I think the problem is the schema for Literal is not quite right.

It would be helpful if you could check the generated schema for an equivalent Enum, and share how it differs from the literal. Also, could you share the version of pydantic you are using? (In case the issue has been addressed in an unreleased pydantic bugfix.)

I appreciate the response @dmontagu , I think that does seem to be the case.
Ill look into the schema generated by Pydantic :)

I added the Pydantic version to the original post. (0.32.2)

Edit:
This is the schema of the example I posted, still looking into it:

{
  "title": "Dog",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "const": "Fred",
      "type": "string"
    },
    "dog": {
      "title": "Dog",
      "anyOf": [
        {
          "const": "dog",
          "type": "string"
        },
        {
          "const": "Dog",
          "type": "string"
        }
      ]
    },
    "pup": {
      "title": "Pup",
      "anyOf": [
        {
          "const": "puppy",
          "type": "string"
        },
        {
          "const": "pup pup",
          "type": "string"
        },
        {
          "const": "pupper",
          "type": "string"
        }
      ]
    }
  },
  "required": [
    "name",
    "dog",
    "pup"
  ]
}

My initial intuition is that SwaggerUI is not displaying elements that do not have a ‘type’ field. looking into it

I think I see what’s going on: pydantic is not generating an anyOf for literals that take only a single value. It seems like the swagger docs don’t do a great job of handling that right now.

I think we need to add first class support for the OpenAPI discriminator pattern into pydantic, as I think that is the most important use case for a single-valued literal (and why the literal functionality was first added). That will probably need to influence the schema design for the single value case.

It might be worth opening an issue on the swagger docs github related to the way they generate a default value for a string marked as const — it should probably be the const value (which it isn’t based on your screenshots).

@dmontagu
Regarding the anyOf, that seems to be the case.

I'm going to look into if there is a different way that the 'anyOf' should be generated for swagger before creating another issue

I no longer believe that this issue is stemming from the fastapi code and will close this issue.

@ashears it is also possible to manually override the example shown in swagger through the schema_extra config setting on the pydantic model; this might get the string to be right for you.

In my experience swagger doesn't render correctly examples with anyof
anyway, even if the schema is correct you end up with just curly braces.
I asked quite recently in gitter iirc, will try to find it.

Le mar. 24 sept. 2019 à 7:00 AM, dmontagu notifications@github.com a
écrit :

@ashears https://github.com/ashears it is also possible to manually
override the example shown in swagger through the schema_extra config
setting on the pydantic model; this might get the string to be right for
you.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tiangolo/fastapi/issues/562?email_source=notifications&email_token=AAINSPT3MYYEVDRYWQKUEW3QLGNGVA5CNFSM4IZWW7CKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7NCEMI#issuecomment-534389297,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAINSPRBEBYL5NQ6ULQDTDLQLGNGVANCNFSM4IZWW7CA
.

yep for instance

class CMsg(BaseModel):
    msg: Union[StrictStr, StrictBool]

FastAPI generated schema (in yaml) seems correct, yet example shows just empty curly braces, I wasnt able to find a relevant swagger ui issue

components:
  schemas:
    CMsg:
      title: CMsg
      required:
        - msg
      type: object
      properties:
        msg:
          title: Msg
          anyOf:
            - type: string
            - type: boolean

@dmontagu

@ashears it is also possible to manually override the example shown in swagger through the schema_extra config setting on the pydantic model; this might get the string to be right for you.

Thanks, This is useful.

@euri10
I agree that it seems to be a SwaggerUI issue handling the anyOf tag

From Swagger doc:

anyOf – the subschemas must be OpenAPI schemas and not standard JSON Schemas.

const keyword is not supported by OpenAPI

So I think that it's more related to a pydantic JSON exporting issue or incompatibility

Thanks for the help here everyone! :clap: :bow:

Thanks for reporting back and closing the issue @ashears :+1:

Was this page helpful?
0 / 5 - 0 ratings