liveBook · Manning

Field validator

As explained in Build Financial Software with Generative AI (From Scratch)

A field validator is a Pydantic annotation or decorator that applies custom validation logic to a model field.

A field validator is a Pydantic decorator that applies custom logic to one model field. It is useful when a field’s validity depends on runtime business data rather than a fixed type or pattern—for example, checking an ACH file’s immediate destination against routing numbers stored in a database. section 8.5.3

A practical field-validator workflow is:

  • Attach @field_validator to the target field and define the validator as a class method. section 8.5.3
  • Receive the field value, call a validation routine, and return it when the business rule succeeds. section 8.5.3
  • Raise a clear ValueError when the value is invalid or when the external validation operation cannot complete. section 8.5.3
  • Consider query frequency and update tests when validation changes which values are accepted. section 8.5.3

Normalizing an audit URL

An audit-log model can use Pydantic’s AnyUrl type for URL validation, then use a field validator in before mode to convert the validated value to a string before database insertion. This keeps storage compatibility inside the model instead of making every database caller perform the conversion. section 9.3.2

Listing 8.17 Pydantic field validator for immediate destination
@field_validator('immediate_destination') #1
@classmethod    #2
def validate_immediate_destination(cls, v):
   try:
      if BankRoutingSql().valid_bank_routing_number(v): #2
         return v #3
      else:  #3
         raise ValueError('immediate_destination #3
➥ is not a valid routing number')  #3
   except Exception: #4
      raise ValueError('Unable to validate #4
➥ immediate_destination')  #4

Trace a database-backed validator that accepts an immediate destination only when the routing number is allowed, and distinguishes invalid values from validation failures. section 8.5.3

Listing 9.22 The AuditLogRecord class
class AuditLogRecord(BaseModel):
…
    ip_address: Optional[IPvAnyNetwork] = Field( #1
        None,
        title="IP Address",
        description="IP address from which the request originated.",
    )
…
    url: Optional[AnyUrl] = Field( #2
        None, 
        title="URL", 
        description="URL accessed by the request.", max_length=255
    )
…
    @field_validator("url", mode="before") #3
    @classmethod #3
    def convert_url_to_str(cls, v: AnyUrl) -> str:  #3
        return str(v)  #3

Compare field validation with pre-processing by converting an AnyUrl value to a database-compatible string inside the model. section 9.3.2

How Build Financial Software with Generative AI (From Scratch) covers it

How deep it goes
Explains decorator structure, runtime lookups, return values, exceptions, preprocessing, performance considerations, and related test updates.
Examples
Uses ACH routing-number checks, file-ID constraints, audit-log URL conversion, and tests that insert and retrieve audit records.
What you can do after
Apply it via Pydantic to enforce runtime business rules and normalize field values before downstream database operations.
How it connects
Connects Pydantic models with database validation, data normalization, exception handling, unit testing, and database persistence.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build Financial Software with Generative AI (From Scratch). The section links point to the parts of the book it draws on.