Metadata-Version: 2.1
Name: goodconf
Version: 2.0b2
Summary: Load configuration variables from a file or environment
Home-page: https://github.com/lincolnloop/goodconf/
Author: Peter Baumgartner
Author-email: pete@lincolnloop.com
License: MIT
Description: Goodconf
        ========
        
        .. image:: https://img.shields.io/travis/lincolnloop/goodconf.svg
            :target: https://travis-ci.org/lincolnloop/goodconf
        
        .. image:: https://img.shields.io/codecov/c/github/lincolnloop/goodconf.svg
            :target: https://codecov.io/gh/lincolnloop/goodconf
        
        .. image:: https://img.shields.io/pypi/v/goodconf.svg
            :target: https://pypi.python.org/pypi/goodconf
        
        .. image:: https://img.shields.io/pypi/pyversions/goodconf.svg
            :target: https://pypi.python.org/pypi/goodconf
        
        A thin wrapper over `Pydantic's settings management <https://pydantic-docs.helpmanual.io/usage/settings/>`__.
        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``:
        
        .. code:: python
        
            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:
        
        .. code:: python
        
            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:
        
        .. code:: shell
        
            python -c "import myproject; print(myproject.conf.config.generate_yaml(DEBUG=True))" > myproject.yaml
        
        Better yet, make it a function and `entry point <https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation>`__ 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.
        
        
        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:
        
        .. code:: python
        
            # Define your GoodConf in `myproject/conf.py`
            from myproject.conf import config
        
            if __name__ == '__main__':
                config.django_manage()
        
        
        Why?
        ----
        
        I took inspiration from `logan <https://github.com/dcramer/logan>`__ (used by
        Sentry) and `derpconf <https://github.com/globocom/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 <https://imagetragick.com/>`__
           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.
        
        .. code:: shell
        
            pip install -e ".[tests]"
        
        
        Run tests
        
        .. code:: shell
        
            pytest
        
Keywords: env,config,json,yaml
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Provides-Extra: yaml
Provides-Extra: tests
Provides-Extra: maintainer
