seandstewart / typical

Typical: Fast, simple, & correct data-validation using Python 3 typing.
https://python-typical.org
MIT License
183 stars 9 forks source link

Is there a way to use choices with values and labels when generating schemas? #199

Closed dodumosu closed 6 months ago

dodumosu commented 1 year ago

A lot of Python libraries/frameworks support the use of choices as collection of <value>/<label> tuples (or even an enum, for example http.HTTPStatus. Is there a specific way to have the labels for such a collection to the generated schema?

I'm considering using typical as a replacement for pydantic, and I already asked a similar question for pydantic here.

Thanks in advance

dodumosu commented 1 year ago

sorry, I wasn't very clear posting this. This idea is to expose the schema via an API endpoint so that another app can render a UI based on the schema. for something like a dropdown with labels and values, serialization like that would be necessary

seandstewart commented 1 year ago

Hey @dodumosu -

Unfortunately, JsonSchema can't express enums in this way.

If I understand correctly, you want a schema something like this:

{
  "type": "array",
  "items": {
    "type": "object",
    "required": ["label", "value"],
    "additionalProperties": false,
    "properties": {
      "label": {"type": "string"},
      "value": {"type": "string"}
    }
  }
}

You could be exceptionally strict and create a unique object type for each enumerated choice, but that will be quite brittle and mean that with every addition or subtraction from your enumeration on the backend, you have a large schema migration on the frontend. In my experience, a solution like the above affords you some flexibility between backend and frontend while allowing your application to evolve.

It can also allow you to opt to change your storage format for these enumerations - perhaps one day you scale to a point where you want to make these choices configurable via updates from an operations team rather than engineers having to update them. In this scenario, you can migrate to storing these enumerations in a database and the frontend is none-the-wiser.