Not So Long Introduction to Pydantic
Umesh Timalsina
September 2, 2020
Prologue
Due to untyped nature of python, validation of datatypes used in your classes can be quite
tricky. Unless used judiciously, this can lead to downstream issues related to use of invalid
datatypes in your python package.
In this post, we explore data validation for python classes using Pydantic
1
Introduction
At its core, pydantic is a data validation and a settings management library. In this post
we will focus more on data validation part. Let’s start with a basic example. While the
documentation is holistic, this blog post can serve as a quick start guide, an extended
overview if you insist .
The code examples presented in this blog post are available in the following GitHub
repository.
2
Let’s create a simple account management problem. We will start with a simple situation
with two types of accounts.
1. SavingsAccount
2. CheckingAccount
Clearly, many aspects of these accounts can be consolidated using an abstract base class
Account. Using pydantic, we can define the base class as:
1 from abc import ABC, abstractmethod
2 from pydantic import BaseModel, Field
3
4
5 class Account(BaseModel, ABC):
6 id: str = Field(
1
https://pydantic-docs.helpmanual.io
2
https://github.com/umesh-timalsina/not-so-long-intro-to-pydantic
1
7 ...,
8 description="The id of the account"
9 )
10
11 account_holder: str = Field(
12 ...,
13 description="The name of the account holder"
14 )
15
16 amount: float = Field(
17 ...,
18 description="The amount in the account in dollars"
19 )
20
21 is_open: bool = Field(
22 default=True,
23 description="A flag indicating whether or not the account is open"
24 )
25
26 @abstractmethod
27 def deposit(self, amount):
28 raise NotImplementedError
29
30 @abstractmethod
31 def close(self):
32 raise NotImplementedError
33
34 def withdraw(self, amount):
35 if self.amount <= amount:
36 self.amount -= amount
37 else:
38 raise ValueError('Cannot withdraw more than available funds.')
39
40 def __repr__(self):
41 return f'<{self.__class__.__name__} {self.id}>'
2