Python

How to Use Pydantic’s Literal Type: A Practical Guide

When it comes to writing reliable Python code, Pydantic’s literal type can be helpful. Pydantic is a handy library for making sure that the data we get is correct, and the literal type adds an extra layer of accuracy. It’s super useful when we want to be very specific about our variables’ values. This removes the errors from wrong inputs and makes our code easier to understand. The literal type works better when dealing with constants, lists of options, or situations where certain values have special meanings.

Syntax:

Here’s a simplified explanation of the Pydantic literal type syntax:

option: Literal['value1', 'value2', 'value3']

To use the Pydantic’s literal inside a model, we define an attribute called “option”. Now, using literal, we are saying that this option can only have one of these values: “value1”, “value2”, or “value3”. This way, we make sure that whatever goes into the option is one of those three choices, and nothing else. It’s like putting a rule on the attribute to keep things accurate and tidy.

Method 1: Pydantic’s Literal Type Real-Scenario Application

In the world of Python programming, ensuring that our code is accurate and error-free is crucial. One tool that helps us achieve this is Pydantic’s literal type. We may think of it as a way to be specific about what values our variables can hold. Pydantic is like a check that evaluates if the data that we’re using is correct, and the literal type adds an extra layer of precision. Let’s dive into a detailed example to see how it works.

Suppose we want to make an online boutique app that helps people plan their dream outfits. We want to ensure that the users can only choose from specific outfit styles. So, use Pydantic’s literal type to make sure that the choices are accurate.

To work on the example, importing the Pydantic library packages is important so that we have the right tools before we get started. We need to import Pydantic’s “BaseModel” and “Literal” classes:

from pydantic import BaseModel

from typing import Literal

Then, we proceed further by defining the “Outfit Model”. So, let’s create a Pydantic model to represent the outfit options. We use the literal type to specify the valid choices:

In this model, we’re saying that the “outfit style” attribute can only have one of these values: “gowns”, “traditional”, “casual”, or “embroidered”.

class OutfitModel(BaseModel):

outfit_style: Literal['traditional', 'embroidered', 'gown', 'casual']

After setting the literals, we now plan an outfit for the client using our “OutfitModel”. We create an instance of it and set the “outfit style” attribute to “traditional”:

outfitstyle = OutfitModel(outfit_style='traditional')

print (outfitstyle)

Here, we follow the rules that we set in the model by choosing a valid “outfit style”.

Sometimes, we come across invalid choices; what if someone tries to choose an invalid outfit style? Let’s say they type in “funky”. If we try to create an outfit plan with an unsupported outfit style, Pydantic catches it and raises an error:

from pydantic import BaseModel

from typing import Literal

class OutfitModel(BaseModel):

  outfit_style: Literal['traditional', 'embroidered', 'gown', 'casual']

#outfitstyle = OutfitModel(outfit_style='traditional')

invalid_outfitstyle = OutfitModel(outfit_style='funky')

#print (outfitstyle)

print (invalid_outfitstyle)

Pydantic lets us know that “funky” is not a valid choice based on our literal type. Ultimately, Pydantic’s literal type helps us ensure that our dream outfit app users only choose from the options that we defined. This way, we prevent the errors caused by incorrect inputs and keep our app running smoothly.

Using Pydantic’s literal type can be a game-changer when we must be specific about our variables’ values. Like our outfit app example, we can use it to ensure that the users stick to the predefined choices. This boosts the accuracy of our code and prevents unexpected errors. Pydantic’s literal type is like a guardian for our data, ensuring everything is just how it should be.

Full code with output:

!pip install pydantic

from pydantic import BaseModel

from typing import Literal

class OutfitModel(BaseModel):

  outfit_style: Literal['traditional', 'embroidered', 'gown', 'casual']

outfitstyle = OutfitModel(outfit_style='traditional')

print (outfitstyle)

Method 2: Selection of Payment Methods

To better understand Pydantic’s literal type, we will do another example where we design an application for online payment methods. Suppose we run any online platform, and for the payment, we want the customers to only choose from specific, valid payment methods which is crucial for smooth transactions. In this scenario, Pydantic’s literal type can be our best strategic plan to enforce these restrictions effectively.

To commence, ensure that we have the right tools for the implementation of the example. Begin by importing the essential components from the Pydantic library. The “BaseModel” class forms the backbone of our model structure, while the “Literal” class can specify the exact, acceptable values:

from pydantic import BaseModel

from typing import Literal

With these components in the project, we are now ready to create a data-structured environment to define and validate the payment methods for our online store.

To define the payment method, we need to define the model for it. So, the next step involves creating a Pydantic model which is “PaymentModel” that serves as the layout for payment options. Design the “PaymentModel” with an attribute named “payment_method”:

class PaymentModel(BaseModel):

payment_method: Literal['credit_card', 'paypal', 'debit_card', 'google_pay']

Within the “PaymentModel”, the “payment_method” attribute is the option to select the payment option. The Pydantic’s literal type is used here. By employing the literal type with a predefined list of acceptable values, we effectively imply that the “payment_method” attribute can only hold any one of these values: “credit_card”, “paypal”, “debit_card”, or “google_pay”.

After getting the model ready, it’s time to validate/process a customer’s payment. We may imagine it as a customer that navigates our online store and initiates a payment. Create an instance of the “PaymentModel”, setting the “payment_method” attribute to “paypal” as a recognized and valid option.

customer_payment = PaymentModel(payment_method='paypal')

We stick with the model’s regulations and selecting an already defined payment method.

To handle the invalid payment methods, Pydantic’s literal type is if there’s an attempt to process a payment using an undefined method such as “cash on delivery”:

from pydantic import BaseModel

from typing import Literal

class PaymentModel(BaseModel):

payment_method: Literal['credit_card', 'paypal', 'debit_card', 'google_pay']

invalid_payment = PaymentModel(payment_method='cash_on_delievery')

print(invalid_payment)

In this case, Pydantic serves as a filter/gate. After recognizing that “cash on delivery” is not among the preapproved options, Pydantic raises an error. This behavior ensures that only the defined payment methods are chosen, ensuring the laws of our online store’s transaction system.

Full code with output:

!pip install pydantic

from pydantic import BaseModel

from typing import Literal

class PaymentModel(BaseModel):

payment_method: Literal['credit_card', 'paypal', 'debit_card', 'google_pay']

customer_payment = PaymentModel(payment_method='paypal')

#invalid_payment = PaymentModel(payment_method='cash_on_delievery')

print(customer_payment)

This example highlights the robust capabilities of Pydantic’s literal type. By predefining specific, allowable values for our variables, we ensure the accuracy and reliability of our code. Whether we are handling the payment methods, user preferences, or any other context that requires sticking to specific rules/options, the literal type gives us the power to maintain a controlled and error-free environment.

Conclusion

Pydantic’s literal type guides our code towards precision and reliability. Its capacity to control the variables with a predefined set of values contributes to code accuracy and diminishes the risk of unexpected errors. As explained in the scenarios of the first and second example of the “payment methods” of this guide, Pydantic’s literal type helps in regulating the selection of defined options in the “assignment” variable, increasing our code’s reliability.

About the author

Omar Farooq

Hello Readers, I am Omar and I have been writing technical articles from last decade. You can check out my writing pieces.