Official doc: Validators - Pydantic
Good to read: python - Pydantic V2 - @field_validator values
argument equivalent - Stack Overflow
import pycountry
def is_valid_iso_639_1(language_code: str) -> bool:
try:
language = pycountry.languages.get(alpha_2=language_code)
return language is not None
except (AttributeError, KeyError):
return False
class TranscribeConfigs(BaseModel):
inputLanguage: str = Field(default="")
outputLanguage: str = Field(default="")
specialWords: List[str] = Field(default=[])
@field_validator('inputLanguage', 'outputLanguage')
@classmethod
def validate_language_code(cls, v):
if v is None or len(v) == 0: # accept optional property
return v
if not re.match(r'^[a-z]{2}$', v):
raise ValueError("Language must be a valid ISO-639-1 two-letter code")
return v
Another way using AfterValidator
(more)
def is_valid_iso_639_1(v: str) -> bool:
# accept null or empty string (optional prop)
if v is None or len(v) == 0:
return v
try:
language = pycountry.languages.get(alpha_2=v)
if language is not None:
return v
raise HTTPException(
status_code=422,
detail="Language must be a valid ISO-639-1 two-letter code",
)
except (AttributeError, KeyError):
raise HTTPException(
status_code=422,
detail="Language must be a valid ISO-639-1 two-letter code",
)
class TranscribeConfigs(BaseModel):
inputLanguage: Annotated[Optional[str], AfterValidator(is_valid_iso_639_1)] = Field(default="", description="ISO 639-1 language code")
outputLanguage: Annotated[Optional[str], AfterValidator(is_valid_iso_639_1)] = Field(default="", description="ISO 639-1 language code")
specialWords: Optional[List[str]] = Field(default=[], description="List of special words to be transcribed")
/docs
/docs
Each endpoint in /docs
displays a schema that defines its responses and inputs. This section explains how to customize these schemas.
Customize schema for each endpoint and don’t use class
To completely remove default 422 schema (source)
Another way for custom response with error code
class ErrorResponse(BaseModel):
detail: str
@app.post("/upload", response_model=UploadResponse, responses={500: {"model": ErrorResponse}})
This doc is useful too.
/docs