Using config files written in Python [closed]

2024/10/5 5:15:02

I've noticed a few Python packages that use config files written in Python. Apart from the obvious privilege escalation, what are the pros and cons of this approach?

Is there much of a precedence for this? Are there any guides as to the best way to implement this?

Just to clarify: In my particular use case, this will only be used by programmers or people who know what they're doing. It's not a config file in a piece of software that will be distributed to end users.

Answer

The best example I can think of for this is the django settings.py file, but I'm sure there are tons of other examples for using a Python file for configuration.

There are a couple of key advantages for using Python as config file over other solutions, for example:

  • There is no need to parse the file: Since the file is already Python, you don't have to write or import a parser to extract the key value pairs from the file.
  • Configuration settings can be more than just key/values: While it would be folly to have settings define their own classes, you can use them to define tuples, lists or dictionaries of settings allowing for more options and configuration than other options. This is especially true with django, where the settings file has to accommodate for all manner of plug-ins that weren't originally known by the framework designers.
  • Writing configuration files is easy: This is spurious, but since the configuration is a Python file it can be edited and debugged within the IDE of the program itself.
  • Implicit error-checking: If your program requires an option called FILE_NAME and that isn't in the settings the program will throw an exception. This means that settings become mandatory and error handling of the settings can be more explicit. This can be a double edged sword, but manually changing config files should be for power editors who should be able to handle the consequences of exceptions.
  • Config options are easily accessed and namespaces: Once you go import settings you can wildly start calling settings.UI_COLOR or settings.TIMEOUT. These are clear, and with the right IDE, tracking where these settings are made becomes easier than with flat files.

But the most powerful reason: Overrides, overrides, overrides. This is quite an advanced situation and can be use-case specific, but one that is encouraged by django in a few places.

Picture that you are building a web application, where there is a development and production server. Each of these need their own settings, but 90% of them are the same. In that case you can do things like define a config file that covers all of development and make it (if its safer) the default settings, and then override if its production, like so:

PORT = 8080
HOSTNAME = "dev.example.com"
COLOR = "0000FF"if SITE_IS_LIVE:import * from production_settings.py

Doing an import * from will cause any settings that have been declared in the production_settings.py file to override the declarations in the settings file.

I've not seen a best practise guideline or PEP document that covers how to do this, but if you wanted some general guidelines, the django settings.py is a good example to follow.

  • Use consistent variable names, preferably UPPER CASE as they are understood to be settings or constants.
  • Expect odd data structures, if you are using Python as the configuration language, then try to handle all basic data types.
  • Don't try and make an interface to change settings, that isn't a simple text editor.

When shouldn't you use this approach? When you are dealing with simple key/value pairs that need to be changed by novice users. Python configs are a power user option only. Novice users will forget to end quotes or lists, not be consistent, will delete options they think don't apply and will commit the unholiest of unholies and will mix tabs and spaces spaces only. Because you are essentially dealing with code not config files, all off these will break your program. On the otherside, writing a tool that would parse through through a python file to find the appropriate options and update them is probably more trouble than it is worth, and you'd be better of reusing an existing module like ConfigParser

https://en.xdnf.cn/q/70519.html

Related Q&A

Model not defined when using foreign key to second model

Im trying to create several relationships between some models such as User and Country. When I try to syncdb, my console outputs "Name Country is not defined". Here is the code: class User(mo…

Sending a POST request to my RESTful API(Python-Flask), but receiving a GET request

Im trying to send a trigger to a Zapier webhook in the form of a POST request containing JSON. It works fine if I just send the POST request through a local python script.What I want to do is create a …

django deploy to Heroku : Server Error(500)

I am trying to deploy my app to heroku. Deploy was done correctly but I got Server Error(500). When I turned DEBUG true, Sever Error doesnt occurred. So I think there is something wrong with loading st…

Should I preallocate a numpy array?

I have a class and its method. The method repeats many times during execution. This method uses a numpy array as a temporary buffer. I dont need to store values inside the buffer between method calls. …

dup, dup2, tmpfile and stdout in python

This is a follow up question from here.Where I want do go I would like to be able to temporarily redirect the stdout into a temp file, while python still is able to print to stdout. This would involve …

How do I write a Class-Based Django Validator?

Im using Django 1.8.The documentation on writing validators has an example of a function-based validator. It also says the following on using a class:You can also use a class with a __call__() method f…

python synthesize midi with fluidsynth

I cant import fluidsynth. [Maybe theres an better module?]Im trying to synthesize midi from python or pygame. I can send midi events from pygame. Im using mingus, and it seemed pyfluidsynth would be g…

Convenient way to handle deeply nested dictionary in Python

I have a deeply nested dictionary in python thats taking up a lot of room. Is there a way to abbreviate something like this master_dictionary[sub_categories][sub_cat_name][attributes][attribute_name][s…

Running tests against existing database using pytest-django

Does anybody know how to run Django Tests using pytest-django against an existing (e.g. production) database? I know that in general, this is not what unit tests are supposed to do, but in my case, I…

Python, Timeout of Try, Except Statement after X number of seconds?

Ive been searching on this but cant seem to find an exact answer (most get into more complicated things like multithreading, etc), I just want to do something like a Try, Except statement where if the …