1

I have a class

class Animal(BaseModel):
    type: str # can be dog, cat or duck        
    voice: str # can woof, meow, quack

As we can see, there are 2 connected variables, because, for example, a dog cannot quack. How to make this so that I have dependencies on the values in two variables in EXACTLY ONE CLASS?

I need all this in order to have a more understandable scheme of the fastapi input parameters.

The point is that in the scheme it was written that the duck croaks, the dog barks, and the cat meows. I'm not really sure that this is possible, but it sounds like someone has already done it.

opeonikute
  • 494
  • 1
  • 4
  • 15
  • Do you want the OpenAPI spec to reflect this dependency between values, or are you (only) looking to validate that the `type` and `voice` values are valid for each other? – MatsLindh Sep 01 '23 at 11:21
  • @MatsLindh I want it to be visible in swagger – herasima1337 Sep 01 '23 at 13:28
  • That isn't supported by the OpenAPI specification as far as I know: https://stackoverflow.com/questions/63209596/how-to-indicate-that-a-parameter-is-conditionally-required-when-another-paramete – MatsLindh Sep 01 '23 at 13:39

1 Answers1

0

If voice has only one option per type then it can be a computed property:

from enum import Enum
from pydantic import BaseModel, computed_field

class AnimalType(Enum):
    DOG = "dog"
    CAT = "cat"
    DUCK = "duck"

class AnimalVoice(Enum):
    WOOF = "woof"
    MEOW = "meow"
    QUACK = "quack"

class Animal(BaseModel):
    type: AnimalType

    @computed_field
    @property
    def voice(self) -> AnimalVoice:
        if self.type == AnimalType.DOG:
            return AnimalVoice.WOOF
        if self.type == AnimalType.CAT:
            return AnimalVoice.MEOW
        if self.type == AnimalType.DUCK:
            return AnimalVoice.QUACK
        raise NotImplementedError(f"Animal type {self.type} not supported")
Matteo Zanoni
  • 3,429
  • 9
  • 27