Skip to main content

Load configuration variables from a file or environment

Project description

https://img.shields.io/travis/lincolnloop/goodconf.svg https://img.shields.io/codecov/c/github/lincolnloop/goodconf.svg https://img.shields.io/pypi/v/goodconf.svg https://img.shields.io/pypi/pyversions/goodconf.svg

A thin wrapper over Pydantic’s settings management. Allows you to define configuration variables and load them from environment or JSON/YAML file. Also generates initial configuration files and documentation for your defined configuration.

Installation

pip install goodconf or pip install goodconf[yaml] if parsing/generating YAML files is required.

Quick Start

Let’s use configurable Django settings as an example.

First, create a conf.py file in your project’s directory, next to settings.py:

import base64
import os

from goodconf import GoodConf, Field
from pydantic import PostgresDsn

class AppConfig(GoodConf):
    "Configuration for My App"
    DEBUG: bool
    DATABASE_URL: PostgresDsn = "postgres://localhost:5432/mydb"
    SECRET_KEY: str = Field(
        initial=lambda: base64.b64encode(os.urandom(60)).decode(),
        description="Used for cryptographic signing. "
        "https://docs.djangoproject.com/en/2.0/ref/settings/#secret-key")

    class Config:
        default_files = ["/etc/myproject/myproject.yaml", "myproject.yaml"]

config = AppConfig()

Next, use the config in your settings.py file:

import dj_database_url
from .conf import config

config.load()

DEBUG = config.DEBUG
SECRET_KEY = config.SECRET_KEY
DATABASES = {"default": dj_database_url.parse(config.DATABASE_URL)}

In your initial developer installation instructions, give some advice such as:

python -c "import myproject; print(myproject.conf.config.generate_yaml(DEBUG=True))" > myproject.yaml

Better yet, make it a function and entry point so you can install your project and run something like generate-config > myproject.yaml.

Usage

GoodConf

Your subclassed GoodConf object can include a Config class with the following attributes:

file_env_var

The name of an environment variable which can be used for the name of the configuration file to load.

default_files

If no file is passed to the load method, try to load a configuration from these files in order.

It also has one method:

load

Trigger the load method during instantiation. Defaults to False.

Use plain-text docstring for use as a header when generating a configuration file.

Environment variables always take precedence over variables in the configuration files.

See Pydantic’s docs for examples of loading:

Fields

Declare configuration values by subclassing GoodConf and defining class attributes which are standard Python type definitions or Pydantic FieldInfo instances generated by the Field function.

Goodconf can use one extra argument provided to the Field to define an function which can generate an initial value for the field:

initial

Callable to use for initial value when generating a config

Django Usage

A helper is provided which monkey-patches Django’s management commands to accept a --config argument. Replace your manage.py with the following:

# Define your GoodConf in `myproject/conf.py`
from myproject.conf import config

if __name__ == '__main__':
    config.django_manage()

Why?

I took inspiration from logan (used by Sentry) and derpconf (used by Thumbor). Both, however used Python files for configuration. I wanted a safer format and one that was easier to serialize data into from a configuration management system.

Environment Variables

I don’t like working with environment variables. First, there are potential security issues:

  1. Accidental leaks via logging or error reporting services.

  2. Child process inheritance (see ImageTragick for an idea why this could be bad).

Second, in practice on deployment environments, environment variables end up getting written to a number of files (cron, bash profile, service definitions, web server config, etc.). Not only is it cumbersome, but also increases the possibility of leaks via incorrect file permissions.

I prefer a single structured file which is explicitly read by the application. I also want it to be easy to run my applications on services like Heroku where environment variables are the preferred configuration method.

This module let’s me do things the way I prefer in environments I control, but still run them with environment variables on environments I don’t control with minimal fuss.

Contribute

Create virtual environment and install package and dependencies.

pip install -e ".[tests]"

Run tests

pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

goodconf-2.0.0.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

goodconf-2.0.0-py2.py3-none-any.whl (8.0 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file goodconf-2.0.0.tar.gz.

File metadata

  • Download URL: goodconf-2.0.0.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2

File hashes

Hashes for goodconf-2.0.0.tar.gz
Algorithm Hash digest
SHA256 dc4d2c5682311fb2b13184df10599373784bb02c71ebd43f3c752034929ddd88
MD5 5f95b10ba6a6c2f3ef7777f1a2abad9d
BLAKE2b-256 9fe679a3c7850c821f0b9981e4160c3cfc81937e8b199decc9c7d0bf2f71d711

See more details on using hashes here.

Provenance

File details

Details for the file goodconf-2.0.0-py2.py3-none-any.whl.

File metadata

  • Download URL: goodconf-2.0.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2

File hashes

Hashes for goodconf-2.0.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 0cb283c7a1cc1856d34a29631b3fdc03710f6e1eb04cd65b0fca38c8b6a01e7a
MD5 6c5205443131874faf4d39ffe293cc70
BLAKE2b-256 f12c05d719cbb66640a3d7de3723b400a1b9a71f047f3fea89f9188845bded99

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page