Similarly to @WarKa's answer, with Pydantic v2:
from typing import Literal, Union, Annotated
from dataclasses import dataclass
from pydantic import RootModel, Field
@dataclass
class DeviceTokenGrant:
grant_type: Literal["urn:ietf:params:oauth:grant-type:device_code"]
client_id: str
device_code: str
@dataclass
class RefreshTokenGrant:
grant_type: Literal["refresh_token"]
refresh_token: str
TokenGrant = RootModel[Annotated[Union[RefreshTokenGrant, DeviceTokenGrant], Field(discriminator="grant_type")]]
async def token(grant: Annotated[TokenGrant, Form()]):
...
Note the use of the discriminator
attribute set on Field
. See https://docs.pydantic.dev/latest/concepts/fields/#discriminator