Skip to content

How best to generate OpenAPI schema with reusable enums? #1303

@calvinwyoung

Description

@calvinwyoung

First check

  • I used the GitHub search to find a similar issue 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.

Description

How can I generate an OpenAPI schema with reusable enum classes?

If I have 2 pydantic models that reference the same enum class. By default, the generated OpenAPI schema will look something like this:

{
  "components": {
    "schemas": {
      "Foo": {
        "title": "Foo",
        "type": "object",
        "properties": {
          "some_enum": {
            "title": "Some Enum",
            "enum": ["VALUE_ONE", "VALUE_TWO"],
            "type": "string"
          }
        }
      },
      "Bar": {
        "title": "Bar",
        "type": "object",
        "properties": {
          "some_enum": {
            "title": "Some Enum",
            "enum": ["VALUE_ONE", "VALUE_TWO"],
            "type": "string"
          }
        }
      }
    }
  }
}

I'm looking for a way to generate something like this instead:

{
  "components": {
    "schemas": {
      "Foo": {
        "title": "Foo",
        "type": "object",
        "properties": {
          "some_enum": {
            "$ref": "#/components/schemas/SomeEnum"
          }
        }
      },
      "Bar": {
        "title": "Bar",
        "type": "object",
        "properties": {
          "some_enum": {
            "$ref": "#/components/schemas/SomeEnum"
          }
        }
      },
      "SomeEnum": {
        "type": "string",
        "enum": ["VALUE_ONE", "VALUE_TWO"]
      }
    }
  }
}

The main use case for this feature is to facilitate client code generation — the first schema will produce 2 separate enum classes in the client code, whereas the second schema will generate a single enum class that's referenced in both the Foo and Bar models. This follows the "Reusable enums" pattern here:
https://swagger.io/docs/specification/data-models/enums/

I recognize that this is related to pydantic as well as fastapi, but given that fastapi has its own OpenAPI layer on top of pydantic, I was hoping to find a solution here.

Is there a recommended way to achieve this behavior?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions