'How to specify a BaseSettings Config's env_file based on a field from the same class?
I want to implement this logic
from pydantic import BaseSettings
class Settings(BaseSettings):
ENVIRONMENT: str = 'local'
SECRET_KEY: str = 'somekey'
class Config:
env_file = ".env.development" if Settings.ENVIRONMENT == "development" else ".env.local"
But I have an error:
NameError: name 'Settings' is not defined
I was trying self.ENVIRONMENT
but it doesn't help.
Solution 1:[1]
Settings.ENVIRONMENT
doesn't work because the Settings
class isn't defined yet by the time it's referenced in the Config
definition. And self.ENVIRONMENT
doesn't work because self
here would refer to the Config
class, and not the Settings
class, which as mentioned, isn't fully defined yet, let alone has loaded the value for ENVIRONMENT
yet.
This design has a sort of circular dependency because the Settings
object needs to be initialized first (from direct __init__
or environment variables or env files) to set an ENVIRONMENT
value, ... but in order for Pydantic to initialize that class, it already needs to know which env_file
to read to get the field values, ... but the env_file
is determined by the ENVIRONMENT
value, ... and so on.
The simple alternative would be to separate them into 2 BaseSettings
classes instead:
class EnvConfig(BaseSettings):
ENVIRONMENT: str = "local"
class Settings(BaseSettings):
SECRET_KEY: str = "somekey"
Then create an instance of EnvConfig
first, then reference that instance in defining Settings
' Config.env_file
:
class EnvConfig(BaseSettings):
ENVIRONMENT: str = "local"
env_config = EnvConfig()
class Settings(BaseSettings):
SECRET_KEY: str = "somekey"
class Config:
env_file = ".env.development" if env_config.ENVIRONMENT == "development" else ".env.local"
$ cat .env.local
SECRET_KEY=localkey
$ ENVIRONMENT=local python test.py
SECRET_KEY='localkey'
$ cat .env.development
SECRET_KEY=developmentkey
$ ENVIRONMENT=development python test.py
SECRET_KEY='developmentkey'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Gino Mempin |