Pydantic validation error for BaseSettings model with local ENV file

Question:

I’m developing a simple FastAPI app and I’m using Pydantic for storing app settings.

Some settings are populated from the environment variables set by Ansible deployment tools but some other settings are needed to be set explicitly from a separate env file.

So I have this in config.py

class Settings(BaseSettings):

    # Project wide settings
    PROJECT_MODE: str = getenv("PROJECT_MODE", "sandbox")
    VERSION: str

    class Config:
        env_file = "config.txt"

And I have this config.txt

VERSION="0.0.1"

So project_mode env var is being set by deployment script and version is being set from the env file. The reason for that is that we’d like to keep deployment script similar across all projects, so any custom vars are populated from the project specific env files.

But the problem is that when I run the app, it fails with:

pydantic.error_wrappers.ValidationError: 1 validation error for Settings
VERSION
  field required (type=value_error.missing)

So how can I populate Pydantic settings model from the local ENV file?

Asked By: ruslaniv

||

Answers:

If the environment file isn’t being picked up, most of the time it’s because it isn’t placed in the current working directory. In your application in needs to be in the directory where the application is run from (or if the application manages the CWD itself, to where it expects to find it).

In particular when running tests this can be a bit confusing, and you might have to configure your IDE to run tests with the CWD set to the project root if you run the tests from your IDE.

Answered By: MatsLindh

The path of env_file is relative to the current working directory, which confused me as well. In order to always use a path relative to the config module I set it up like this:

env_file: f"{pathlib.Path(__file__).resolve().parent}/config.txt"
Answered By: kevinzehnder
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.