
Security News
npm ‘is’ Package Hijacked in Expanding Supply Chain Attack
The ongoing npm phishing campaign escalates as attackers hijack the popular 'is' package, embedding malware in multiple versions.
.. image:: https://github.com/lincolnloop/goodconf/actions/workflows/test.yml/badge.svg?branch=main&event=push :target: https://github.com/lincolnloop/goodconf/actions/workflows/test.yml?query=branch%3Amain+event%3Apush
.. image:: https://results.pre-commit.ci/badge/github/lincolnloop/goodconf/main.svg :target: https://results.pre-commit.ci/latest/github/lincolnloop/goodconf/main :alt: pre-commit.ci status
.. 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/TOML
file. Also generates initial configuration files and documentation for your
defined configuration.
pip install goodconf
or pip install goodconf[yaml]
/
pip install goodconf[toml]
if parsing/generating YAML/TOML
files is required. When running on Python 3.11+ the [toml]
extra is only required for generating TOML files as parsing
is supported natively.
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")
model_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
.
GoodConf
^^^^^^^^^^^^
Your subclassed GoodConf
object can include a model_config
dictionary 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:
Dotenv (.env) files <https://pydantic-docs.helpmanual.io/usage/settings/#dotenv-env-support>
_Docker secrets <https://pydantic-docs.helpmanual.io/usage/settings/#secret-support>
_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
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()
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:
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.
Create virtual environment and install package and dependencies.
.. code:: shell
pip install -e ".[tests]"
Run tests
.. code:: shell
pytest
Releases are done with GitHub Actions whenever a new tag is created. For more information,
see <./.github/workflows/build.yml>
_
FAQs
Load configuration variables from a file or environment
We found that goodconf demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The ongoing npm phishing campaign escalates as attackers hijack the popular 'is' package, embedding malware in multiple versions.
Security News
A critical flaw in the popular npm form-data package could allow HTTP parameter pollution, affecting millions of projects until patched versions are adopted.
Security News
Bun 1.2.19 introduces isolated installs for smoother monorepo workflows, along with performance boosts, new tooling, and key compatibility fixes.