Package: django-configen
django-configenA Django app for generating server configuration files, such as for Nginx,
uWSGI, Gunicorn etc. in a DRY way.IntroductionThe problem:Configuration files stay pretty much the same for different projects. You're
often copying these config files from other projects and then only modifying
the file paths, domain name and other variables which are unique to this
project.This process is error-prone and repetitive.The solution:This app solves it by generating config files from templates. So, instead
of maintaining config files, you maintain their templates. And then use this
app to render the templates with the project specific variables.You can copy the original templates to multiple projects and stay assured that
final generated config files will have appropriate paths and other variables.Installationpip install django-configenAddconfigentoINSTALLED_APPSlist:INSTALLED_APPS=[# ...'configen',]Add these settings to configure configen:# where configen will look for config templatesCONFIGEN_TEMPLATES_DIR=os.path.join(BASE_DIR,'configs/templates')# where configen will keep the generated filesCONFIGEN_OUTPUT_DIR=os.path.join(BASE_DIR,'configs/output')# config context processorsCONFIGEN_CONFIG_PROCESSORS=['configen.config_processors.common',]CONFIGEN_CONFIG_PROCESSORSis a list of config processor functions. They are
similar to Django's context processors and whatever data they return will be
made available to the config templates during compiling.Basic usageThe config processor that you just configured above
(configen.config_processors.common),
makes some common and helpful variables available for you in the config templates.These variables are:settings: current settings file.project_dir_name: name of the project directoryvirtualenv: path to current virtualenv.python_interpreter: path to current python interpreterNow you can write templates for your config files using Django's template
syntax.For this example, you can create annginx.confinsideconfigs/templates/directory and put this code in it:server {

    location /media  {
        alias {{ settings.MEDIA_ROOT }};
    }

    location /static {
        alias {{ settings.STATIC_ROOT }};
    } 
}Run this command to compile the template:python manage.py configenIt will generate the configuration file from the given template and populate
it with the given variables. The generated file will be inside theconfigs/outputdirectory.Providing extra context variablesA quick way to provide extra context variables is by usingCONFIGEN_DEFAULT_CONTEXTsetting:CONFIGEN_DEFAULT_CONTEXT={'*':{# variables listed here will be available to# all templates'project_name':'example',},'nginx.conf':{# variables listed here will be available only to# nginx.conf template'domain':'example.com',},'uwsgi.ini':{# variables listed here will be available only to# uwsgi.ini template'module':'myproject.wisgi',}}It should be mentioned that the context returned byCONFIGEN_DEFAULT_CONTEXTwill be overridden by context variables returned by config processors if the
names collide.Writing custom config processor functionsUsingCONFIGEN_DEFAULT_CONTEXTsettings gives you a quick and basic way
to provide context variables to the templates. However, if you want to do some
extra calculations before returning the variables, this pattern becomes limiting.For those cases, configen supports providing context data from functions.
It works  similar to Django's context processors. However, to avoid name
confusion, we call them config processors.This is what a config processor function looks like:defconfig_processor(template_name,*args):return{'var':'hello'}The config processor will be passed atemplate_nameargument which will let it
it know the name of the template being compiled. This is useful if you want to
return different data depending on the template.To use your config processor, add this to your settings:CONFIGEN_CONFIG_PROCESSORS=['configen.config_processors.common','path.to.config_processor',]The order in which you list the config processors matters. The last config
processor will override the context variables from the previous processors in
case there are name collisions.If you run theconfigencommand again, the variables returned by your config
processor will be available to the config templates.Passing arguments to config processors from command lineYou can pass extra arguments to your config processors from command line using
the--extracommand option:python manage.py configen --extra arg1 arg2These arguments will be available underargsargument in your config processor.See documentation for--extraoption for more.Changing the name of the output fileConfigen will save the output files with same name as the input template files.
This is okay if you have a single project but can become problematic if you
have multiple projects.Suppose, you have two projects and both have a config template callednginx.conf.
The generated config files will also be callednginx.conffor both projects.
Now you can't copy both of these files in Nginx's config directory because of
the name collision.So the general workaround for this problem to rename the files with the project
name, likeproject1_nginx.conf,project2_nginx.confand this problem is
solved.Configen provides two ways to change the name of the output file.First, the simple way: UsingCONFIGEN_DEFAULT_METAsetting:CONFIGEN_DEFAULT_META={'*':{'outfile':'project1_{template_name}'}}{template_name}will be automatically replaced by the name of the template
including the file extension.Just like withCONFIGEN_DEFAULT_CONTEXTsetting, you can create keys
with the names of your config templates if you only want to override a particular
template's output file name.Another way to provide the meta data to configen is by returning a second dict from your
config processor like this:defconfig_processor(template_name,*args):context={'var':'hello'}meta={'outfile':'project1_%s'%template_name}return(context,meta)Currently, there's only one option supported for meta data -outfile.SettingsCONFIGEN_TEMPLATES_DIRPath to the directory where configen will look for the config templates.CONFIGEN_OUTPUT_DIRPath to the directory where configen will keep the generated config files.CONFIGEN_CONFIG_PROCESSORSA list containing Python path to functions which will be called during generation
of each config template.Example:CONFIGEN_CONFIG_PROCESSORS=['configen.config_processors.common','your.custom.processor',]Theconfigen.config_processors.commonconfig processor provided by configen
makes some commonly used variables available to you in your config templates:settings: current settings file.project_dir_name: name of the project directoryvirtualenv: path to current virtualenv.python_interpreter: path to current python interpreterYou can override these variables from your custom config processors, or leave
this processor out of the setting if you don't want it.CONFIGEN_DEFAULT_CONTEXTA dictionary containing default context variables for generating config files.Example:CONFIGEN_DEFAULT_CONTEXT={'*':{# will be passed to all templates'project_name':'Example',},'nginx.conf':{# will be passed only to nginx.conf template'domain':'example.com',},'uwsgi.ini':{'socket':'/tmp/example.sock',},}CONFIGEN_DEFAULT_METAA dictionary for providing meta configuration information to configen about a
template.Currently only option supported isoutfile.Example:CONFIGEN_DEFAULT_META={'*':{# will be used for all templates'outfile':'myproject_{template_name}',},'nginx.conf':{# will be used only for nginx.conf template'outfile':'myproject_nginx_blah_blah.conf',},}Command line optionstemplateOptional. Name of the template to compile. It should be relative to the path
set inCONFIGEN_TEMPLATES_DIRsetting. If not provided, all the templates
present in the directory set byCONFIGEN_TEMPLATES_DIRsetting are compiled.Example:python manage.py configen nginx.conf--printPrint the compiled template to stdout. Useful if you want to inspect the output
without creating/overwriting the output file.Example:python manage.py configen --print--extraExtra arguments that you want to pass to your config processor functions.Example:python manage.py configen --extra arg1 arg2And then access these arguments like this:defconfig_processor(template_name,*args):print(args)# output: ('arg1', 'arg2',)Important:Doing--extra arg1=hello arg2=worldwill not work like you
would expect.arg1=hellowill be parsed as a whole, instead of argument name
and value.The value your config processor will recieve is this:defconfig_processor(template_name,*args):print(args)# output: ('arg1=hello', 'arg2=world',)Hence, we used the word "arguments" and not "keyword-arguments". You can't pass
arbitrary named keyword arguments via command line, at least not withargparsewhich is used by Django to parse commands.If you want to be able to receive named keyword arguments, you'll need to parse
these arguments yourself.--verbosityThe command will print some debug output while compiling templates. You can turn
it off like this:python manage.py configen --verbosity 0LicenseBSD-3-Clause