4

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?

ruslaniv
  • 458
  • 1
  • 6
  • 14
  • 1
    Your example works for me. Perhaps `config.txt` is not in the application's working directory? Have you tried using an absolute path? – Anthony Carapetis Apr 21 '22 at 06:27
  • Make sure the current working directory (i.e. where you launch the application from) is the directory with `config.txt`. – MatsLindh Apr 21 '22 at 06:34
  • @AnthonyCarapetis both `config.py`and `confix.txt` are in the same directory. So the main `app.py` file is in the root of the project and those two setting files are in the `/settings/` directory – ruslaniv Apr 21 '22 at 06:44
  • Then the `config.txt` file is in the wrong location - the current working directory is the directory where _you are running your application from_, not the same directory as the config.py directory. – MatsLindh Apr 21 '22 at 08:20
  • @MatsLindh Yes, you are absolutely right! No matter how much time I've spent with python, there are two things I just never get right - relative vs absolute imports and current working directory )) Would you mind posting it as answer so I can accept it? – ruslaniv Apr 25 '22 at 10:39

2 Answers2

7

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.

MatsLindh
  • 49,529
  • 4
  • 53
  • 84
3

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"