• Stars
    star
    128
  • Rank 281,044 (Top 6 %)
  • Language
    Python
  • License
    MIT License
  • Created over 6 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Transparently load variables from environment or JSON/YAML/TOML file.

Goodconf

https://github.com/lincolnloop/goodconf/actions/workflows/test.yml/badge.svg?branch=main&event=push pre-commit.ci status

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] / pip install goodconf[toml] if parsing/generating YAML/TOML 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

Releasing a new version to PyPI:

export VERSION=X.Y.Z
git tag -s v$VERSION -m v$VERSION
git push --tags
rm -rf ./dist
hatch build
hatch publish
gh release create v$VERSION dist/goodconf-$VERSION* --generate-notes --verify-tag

More Repositories

1

python-qrcode

Python QR Code image generator
Python
4,287
star
2

salmon

A simple monitoring system.
Python
478
star
3

amygdala

RESTful HTTP client for JavaScript powered web applications
JavaScript
392
star
4

django-layout

Django project template layout
Python
286
star
5

django-startproject

Boilerplate code for new Django projects.
Python
238
star
6

django-dynamic-raw-id

(formerly known as django-salmonella) A raw_id_fields widget replacement that handles display of an object's string value on change and can be overridden via a template.
Python
161
star
7

django-debug-logging

A plugin for the Django-Debug-Toolbar to provide statistic logging and a UI for reviewing the logs.
Python
103
star
8

django-webserver

Production webservers as a Django management command
Python
86
star
9

django-production

production settings for Django
Python
77
star
10

generator-frigate

Yeoman generator for webapp development with React, webpack hot reloading, es6 (babel), sass, karma and BrowserSync as a development server/proxy.
JavaScript
44
star
11

django-geotagging

Generic geotagging app built on GeoDjango
Python
43
star
12

lincoln-loop-deploy

An easy-to-use Fabric script for deploying Python projects
Python
41
star
13

python-package-manager-shootout

Benchmarking various Python package managers
HTML
41
star
14

django-cpserver

Management commands for serving Django via CherryPy's built-in WSGI server
Python
41
star
15

salt-stats

A collection of modules for collecting stats
Python
37
star
16

django-jsonit

Helpers for working with JSON responses in your Django project.
Python
35
star
17

django-alive

Healthchecks for Django
Python
32
star
18

django-protected-files

A Django application that lets you serve protected static files via your frontend server after authorizing the user against django.contrib.auth.
Python
32
star
19

round-up

Links and notes from the Django Round-Up podcast
30
star
20

emailed-me

A mini-site for checking Google's Gmail feed with Oauth.
Python
29
star
21

django-beancounter

Django-beancounter is a simple app I built to track my income and expenses.
JavaScript
26
star
22

django-ft-cache

A fault-tolerant pylibmc cache backend for Django
Python
24
star
23

django-render

Render unknown Django model instances based on their content type.
Python
21
star
24

saltdash

A read-only dashboard for Salt jobs
Python
21
star
25

django-kwalitee

A suite of scripts to measure the "kwalitee" of a Django project.
Python
21
star
26

django-selenium-intro

Introduction to Django Selenium blog post example
Python
20
star
27

crossing

JavaScript URL utility library
JavaScript
17
star
28

jquery.shuffleLetters

A fork of martinaglv's shuffleLetters discussed here: http://tutorialzine.com/2011/09/shuffle-letters-effect-jquery/
JavaScript
16
star
29

django-mailfriend

Generic "mail this to a friend" app for Django
Python
13
star
30

django-mineral

A collection of templates/widgets for rapid prototyping
JavaScript
12
star
31

django-launchpad

A simple application to track mailing list signups and unsubscribes. Useful for pre-launch signup pages.
Python
11
star
32

pyuwsgi-wheels

Wheel builder for pyuwsgi
Python
10
star
33

fab-pave

A Fabric script for paving a single web/database server
Python
8
star
34

django-redmine

A Django application to connect to an existing Redmine database
Python
8
star
35

django-locations

International location app following ISO 3166 standards
Python
7
star
36

django-pyuwsgi

Use django-webserver instead
Python
7
star
37

learn-backbone-integration

Syncing Backbone.js with Django
JavaScript
7
star
38

memcache-top

Automatically exported from code.google.com/p/memcache-top
Perl
5
star
39

python-realtimemagic

WorkInProgress. A set of tools to make writting a realtime sockjs server easy(er)
Java
5
star
40

django-paginav

A Django template pagination navigation tag
Python
4
star
41

paaws

CLI for Paaws
Python
4
star
42

pkg-uwsgi-python

uWSGI for Python Debian/Ubuntu package builder
4
star
43

django-libsql

libsql database backend for Django
Python
3
star
44

django-safe-admin-emails

Provides support for making sure sensitive information does not appear in admin emails.
3
star
45

Colloquy-MenuBar-Notifier-Plugin

An unobtrusive notifier for Colloquy.
Python
3
star
46

django-smatic

Python
3
star
47

jquery-slidify

A graphical range selector for jQuery
JavaScript
3
star
48

external-api-integration

Post subversion commits as Basecamp comments
Python
3
star
49

ecs-task

Helper for registering new task definitions on AWS ECS and updating associated services.
Python
3
star
50

flexmap

A HTML/CSS based sitemap
CSS
2
star
51

threads

Threads, the front-end
JavaScript
2
star
52

docker-graphite-api-grafana

JavaScript
2
star
53

element-queries-example

A news website layout with an article component that uses element queries.
HTML
2
star
54

django-linkback

An admin widget to show a link back to the original objects in foreign keys.
Python
2
star
55

docker-sentry

Python
1
star
56

terraform-aws-ecs-service-update

Terraform module to update Services and run Tasks on Amazon ECS
HCL
1
star
57

docker-google-auth-proxy

1
star
58

vectorprime

Lincoln Loop's hubot
CoffeeScript
1
star
59

django-static-installer

A static file dependency downloader/manager
Python
1
star
60

flexbox-fridays

The website for Lincoln Loop's Flexbox Fridays research project.
CSS
1
star
61

docker-nginx-push-stream

Build Nginx push stream module packages for Ubuntu 14.04
1
star
62

django-geotagging-new

An application for transparently geotagging your models.
Python
1
star
63

itinerary

Lightweight routing forked from Backbone, decoupled, and (soon to be) enhanced.
JavaScript
1
star
64

web-design-regularly

Landing page for LL's web design weekly
CSS
1
star
65

windmills

Stop Tilting at Windmills - Spotting Bottlenecks
Python
1
star
66

blinken-bloop

For Django Dash 2013.
CSS
1
star
67

crossing-react-router-demo

A demo showing using Crossing to manage URLs in a react-router based application
JavaScript
1
star