Method 1: Using Pydantic Enums for Improved Data Consistency
Pydantic Enums are like special tools in the Pydantic library that can help keep our data organized and accurate in Python programs. Imagine we have a list of choices and we want to make sure that people only pick from that list. Enums help us with that. Here’s how we can use the Pydantic Enums for improved data consistency:
Before we start with the Pydantic Enums, the prerequisites are to ensure that we have the Pydantic packages installed in our compiler. We will work on the online “Google Colab” Python compiler. To install the Pydantic on the Google Colab, we use the following command:
After adding the Pydantic packages to the project, we want to import the tools from these packages. So, using the following commands bring these necessary tools from Python.
from pydantic import BaseModel
After importing the necessary modules/tools, let’s create the Pydantic’s Enums. To create the Enums, we have to define the “Enum” class which specifies the values for our field. We can imagine the Enums as having a few options to choose from. Enum helps us to list them nicely, the “Enum” class takes the two parameters as its parameter “str” and the “Enum” itself. Then, we define the possible values/options of our field for the Enum. This can be done following the mentioned code:
request= "pending"
application= "approved"
letter = "rejected"
After defining the Enum, we define a model that uses the Enum for the fields that require consistent values or assign the values to the fields of the Enum. It is like creating a form for some items from which one of the options should be picked. We use Pydantic to set up this form and create a model with the “list” name that is inherited from the Pydantic’s BaseModel. The required fields for this model is the name and the status:
name: str
status: StatusEnum
Once this is done, we create an instance for the data. Now, we can use the form/model to check what option we picked. Pydantic makes sure that the choice is one of the options that we listed:
list = list(**data)
If we try to pick something that is not on our list, Pydantic tells us that the option is not there. If we want to know what we picked earlier from the list, Pydantic helps us with that and we can see the choices that we listed by accessing the Enum values using the “Enum” class itself.
print(item_dump)
StatusEnum.application
This is the code for the example that is previously mentioned with the output:
from pydantic import BaseModel
class StatusEnum(str, Enum):
request = "pending"
application = "approved"
letter = "rejected"
class Item(BaseModel):
name: str
status: StatusEnum
data = {"name": "Example Item", "status": "approved"}
item = Item(**data)
item_dump = item.model_dump()
print(item_dump)
StatusEnum.application
From the output, it is visible that using Pydantic Enums is like having a competent help. It makes sure that only the right choices are involved. This is helpful because it keeps our data nice and tidy, and it stops the mistakes from happening. Plus, it makes our code easy to read using good names for the choices. Also, Pydantic Enums work best when we have a clear list of choices. Enums raises the validation error and might not be the best fit if the choices can change or come from somewhere else.
Method 2: Using Pydantic Enum for the Real-World Applications
Suppose we are building a task management app to keep track of our daily tasks. To ensure an accurate and consistent data, we decide to implement the Pydantic Enums. For instance, let’s assume our tasks can have one of three statuses “To-Do”, “In Progress”, and “Done”. To make sure that no incorrect statuses come in, we can use the Pydantic Enums. So, after installing the important Pydantic packages, we create the “WorkStatus Enum”. We begin by designing an “Enum” class that enlists the allowed task statuses. The enlist task statuses in this “Enum” class are the to-do tasks, in-progress tasks, and the tasks that are already done.
from pydantic import BaseModel
class WorkStatusEnum(str, Enum):
TODO = "todo"
IN_PROGRESS = "in_progress"
DONE = "done"
After we define the Enum workstatus, we build the workmodel to construct a Pydantic model, incorporating the WorkstatusEnum for the tasks’ status. The fields for this model are the “task_priority” and the “status” of the tasks. The data type for the task priority is “str” and we pass the “Enum” class as workstatus that we created earlier to the “status” field.
task_priority: str
status: WorkStatusEnum
To enforce the valid status, the workModel now acts as a filter or a gate to ensure that only legitimate statuses are used. Here, we create the instance for the “task_data” workmodel where we define the corresponding values for the enlisted fields in the Enum workstatus. We specify the task_priority for the task to be “wash dishes” and its status is “in progress”. Then, we create the object for this instance.
At this point, we can also validate the status if we provide some other value of status than it is described in the Enum workstatus required fields. Then, Pydantic raises the validation error here.
task = workModel(**task_data)
#invalid_task_data = {"task_priority": "Invalid Task", "status": "invalid_status"}
#invalid_task = TaskModel(**invalid_task_data) # Raises validation error
Pydantic’s model also handles the transformation between the Enum values and their string forms during serialization (converting a complex data to strings) and deserialization. This can be done as follows:
print(task_dump)
We can easily access the Enum values through the “Enum” class itself in the following way:
By applying the Pydantic Enums in this scenario, we ensure that only the accurate task statuses are used, diminishing the possibility of mistakes. This approach also improves the clarity of our code by explicitly showing the permissible options for task statuses.
Here’s the code for the example:
from pydantic import BaseModel
class WorkStatusEnum(str, Enum):
TODO = "todo"
IN_PROGRESS = "in_progress"
DONE = "done"
class workModel(BaseModel):
task_priority: str
status: WorkStatusEnum
task_data = {"task_priority": "Wash dishes", "status": "in_progress"}
task = workModel(**task_data)
#invalid_task_data = {"task_priority": "Invalid Task", "status": "invalid_status"}
#invalid_task = TaskModel(**invalid_task_data) # Raises validation error
task_dump = task.model_dump()
print(task_dump)
WorkStatusEnum.TODO
Conclusion
Pydantic Enums are like trusted tools for keeping the data in check within Python programs. They help ensure that we only use the right choices, avoiding mix-ups and keeping our code easy to read. We have done two examples of the Pydantic Enums in this article. Each example explains how we can implement the Pydantic Enums for the real-world applications to improve the data consistency. Whether handling task statuses, user roles, or other options, Pydantic Enums ensures that our programs work smoothly and don’t get tangled up.