🐍 Environment variables in Python
Read The Twelve Factor App for context.
Note: Sorted by number of downloads.
Pydantic
- Recommended by FastAPI
from pydantic import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
settings = Settings(_env_file='.env')
Python-dotenv
- Recommended by Flask
- Used internally by Pydantic, environs, Dynaconf, etc.
from dotenv import load_dotenv, dotenv_values
load_dotenv() # read using os.environ["KEY"]
Does NOT handle types.
Django-environ
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()
# False if not in os.environ
DEBUG = env('DEBUG')
# Raises django's ImproperlyConfigured exception if SECRET_KEY not in os.environ
SECRET_KEY = env('SECRET_KEY')
# Parse database connection url strings like psql://user:[email protected]:8458/db
DATABASES = {
# read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
'default': env.db(),
# read os.environ['SQLITE_URL']
'extra': env.db('SQLITE_URL', default='sqlite:////tmp/my-tmp-sqlite.db')
}
CACHES = {
# read os.environ['CACHE_URL'] and raises ImproperlyConfigured exception if not found
'default': env.cache(),
# read os.environ['REDIS_URL']
'redis': env.cache('REDIS_URL')
}
Mainly for Django.
Python Decouple
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
EMAIL_HOST = config('EMAIL_HOST', default='localhost')
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
Environs
- Used by cookiecutter-flask
from environs import Env
env = Env()
env.read_env() # read .env file, if it exists
# required variables
gh_user = env("GITHUB_USER") # => 'sloria'
secret = env("SECRET") # => raises error if not set
# casting
max_connections = env.int("MAX_CONNECTIONS") # => 100
ship_date = env.date("SHIP_DATE") # => datetime.date(1984, 6, 25)
ttl = env.timedelta("TTL") # => datetime.timedelta(0, 42)
log_level = env.log_level("LOG_LEVEL") # => logging.DEBUG
# providing a default value
enable_login = env.bool("ENABLE_LOGIN", False) # => True
enable_feature_x = env.bool("ENABLE_FEATURE_X", False) # => False
# parsing lists
gh_repos = env.list("GITHUB_REPOS") # => ['webargs', 'konch', 'ped']
coords = env.list("COORDINATES", subcast=float) # => [23.3, 50.0]
# parsing dicts
gh_repos_priorities = env.dict(
"GITHUB_REPO_PRIORITY", subcast_values=int
) # => {'webargs': 2, 'konch': 3}
Dynaconf
# config.py
from dynaconf import Dynaconf
settings = Dynaconf(
settings_files=['settings.toml', '.secrets.toml'],
)
assert settings.key == "value"
# settings.toml
key = "value"
a_boolean = false
number = 1234
a_float = 56.8
a_list = [1, 2, 3, 4]
a_dict = {hello="world"}
[a_dict.nested]
other_level = "nested value"
# .secrets.toml
password = "s3cr3t"
token = "dfgrfg5d4g56ds4gsdf5g74984we5345-"
message = "This file doesn't go to your pub repo"
export DYNACONF_NUMBER=789
export DYNACONF_FOO=false
Also loads .env
file automatically.
Hydra
- By Facebook
Mainly for Machine Learning.
Comments