Skip to content

Latest commit

 

History

History
67 lines (39 loc) · 1.46 KB

File metadata and controls

67 lines (39 loc) · 1.46 KB

You prefer self documenting code

Taking all of the code in the previous examples, we end up with the following.

from datetime import datetime

from Typing import Optional

from pydantic import (
    BaseModel,
    Field.
    field_validator,
    ValidationError
)

class CheckIfInvoiceIsPaidRequest(BaseModel):
    invoice_id: int = Field(alias="invoiceId")

    @field_validator("invoice_id")
    def invoice_id_is_more_than_zero(cls, invoice_id):
        if invoice_id <= 0:
            raise ValidationError("invoice_id must be more than zero")
        return invoice_id


class InvoicePaymentStatusResponse(BaseModel):
    invoice_id: int = Field(alias="invoiceId")
    invoice_paid: bool = Field(alias="invoicePaid")
    invoice_paid_date: Optional[datetime] = Field(alias="invoicePaidDate")
    

For comparison, a similar object without Pydantic would require much more code. The more code you write to handle generic validation the less readable your code ends up.

Self documenting code is about readability, intent, and context.

# Without Pydantic
import json

class CheckIfInvoiceIsPaidRequest: 
    def __init__(self, invoice_id: int, *args, **kwargs):
        self.invoice_id = invoice_id


# request JSON

request_data = json.loads({"invoiceId": 123})

invoice_id = request_data["invoiceId"]

if type(invoice_id) == int and invoice_id > 0:
    request = CheckIfInvoiceIsPaidRequest(invoice_id=invoice_id)

NEXT

PREVIOUS