Pydantic-Settings: Powerful Application Configuration Management.

Application config, environmental variables and secrets, all validated and available with ease.


This powerful library, built on top of Pydantic, provides an elegant way to define and manage settings in your Python applications. In this article, we’ll explore the installation process, delve into the basics, and showcase some examples to help you harness the full potential of Pydantic-Settings.

This is part one of a two part article, there is a lot to cover and so this iteration goes over installation and basic usage. Another will shortly follow that covers more advanced topics, but this one is in itself is absolutely enough to get started.

Important note, this library used to be a part of Pydantic proper until quite recently, so you may find that a bit of googling doesn’t provide that much for Pydantic-Settings as a standalone lib.

Get Started

I’m a fan of Poetry, so I’ll reference that here, but you can use any of the package management flavours you fancy.

poetry add pydantic-settings 

And you’re good to go.

So, the whole point is to import and validate application settings, environmental variables, secrets, etc. into a single config object that can be referred to throughout your application, something that is not particularly easy, elegant or performant with a mountain of os.environ.get() calls everywhere. How we do this is very simply a class that inherits the provided BaseSettings class.

from pydantic_settings import BaseSettings


class AppSettings(BaseSettings):
    mailchimp_api_key: str


app_settings = AppSettings()


def main():
    print(f"Mailchimp API key is {app_settings.mailchimp_api_key}")


if __name__ == "__main__":
    main()

Running this returns the following:

pydantic_core._pydantic_core.ValidationError: 1 validation error for AppSettings
mailchimp_api_key
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.7/v/missing

Fantastic, we have the most rudimentary validation that checks an attribute is actually available to our application, and we’ve not actually done anything ourselves at all. Let’s see what happens if we give it what it’s asking for with environmental variables.

$ MAILCHIMP_API_KEY=foo python main.py
Mailchimp API key is foo

Super easy peasy. Now, what if you have your environmental variables in a .env file? For that we simply add a model_config attribute to our AppSettings class like so…

from pydantic_settings import BaseSettings, SettingsConfigDict


class AppSettings(BaseSettings):
    mailchimp_api_key: str

    model_config = SettingsConfigDict(env_file='.env')

Now, we can move our variables off the CLI and into a .env file.

# .env
MAILCHIMP_API_KEY=foo

$ python main.py
Mailchimp API key is foo

In the real world, we often have multiple .env files to reflect the different environments our application will live in, examples would be development, testing and production. Whilst the above example reflects how we would go about a single environmental file, how I would go about defining the settings class based on the actual environment would be something like below:

import os
from pydantic_settings import BaseSettings, SettingsConfigDict


class AppSettingsBase(BaseSettings):
    mailchimp_api_key: str


class AppSettingsDev(AppSettingsBase):
    model_config = SettingsConfigDict(env_file='.env.dev')


class AppSettingsTesting(AppSettingsBase):
    model_config = SettingsConfigDict(env_file='.env.test')


class AppSettingsProd(AppSettingsBase):
    model_config = SettingsConfigDict(env_file='.env')


def load_settings():
    return {
        "dev": AppSettingsDev,
        "test": AppSettingsTesting,
        "production": AppSettingsProd
    }[os.environ.get("ENV", "production")]()


def main(app_settings: AppSettingsBase):
    print(f"Mailchimp API key is {app_settings.mailchimp_api_key}")


if __name__ == "__main__":
    app_settings = load_settings()
    main(app_settings)


$ python main.py 
Mailchimp API key is bar

$ ENV=production python main.py 
Mailchimp API key is bar

$ ENV=dev python main.py 
Mailchimp API key is foo

$ ENV=test python main.py 
Mailchimp API key is baz

By loading an AppSettingsBase-derived object based on a defined environment, we can have as many versions of the application as we want.

Leave a Reply

Your email address will not be published. Required fields are marked *

Learn how your comment data is processed to reduce spam here.

Achieve your goals through technology.

Get in touch to discuss your challenges and goals, we are here to make your business succeed.

First Name
Email
Phone
The form has been submitted successfully!
There has been some error while submitting the form. Please verify all form fields again.

Or, visit our contact page here.

Our Services

Web Development

From simple landing pages to complex web applications, we have you covered.

Operational systems

Automation

By transforming repetitive, manual tasks into automated systems, you can free up precious time to actually run your business.

Maintenance

Some much needed TLC for existing projects.