Generate Literal in Runtime

I want to create a pydantic Model with a Literal field, but the options should be derived from a list. Something like this:

from pydantic import BaseModel
from typing import Literal

opts=['foo','bar']

class MyModel(BaseModel):
    select_one : Literal[opts]

Is there some way this could be solved by enumeration?

Answer

In order for this to work, the Literal needs to be over a tuple (see also here).

There are several options, depending on your situation:

from pydantic import BaseModel
from typing import Literal

# First option:
class MyModel(BaseModel):
    select_one: Literal['foo', 'bar']

# Second option:
opts_tuple = ('foo', 'bar')
class MyModel(BaseModel):
    select_one: Literal[opts_tuple]

# Third option:
opts_list = ['foo', 'bar']
class MyModel(BaseModel):
    select_one: Literal[tuple(opts_list)]