Package: konf
KonfTiny tool that designed to solve problems of Python configuration files located outside of VCS.Installation:pipinstallkonfRunning tests:nosetestsWhy Konf?Sometimes there is a need to get some settings outside of Python code and then to use them in an application. This can be secret keys, authentication tokens, URLs of third-party services, or other settings which depends on the server. Developers (or IT engineers) are faced with several challenges:Validation of data importing from config. It may be simple typing, matching with range of possible values or with regexes.Respect of all settings. Check that config contains all required data. Also, it can be useful to check that there are no extra (redundant) things inside a config (because it can be the data, forgotten to consider in an application).Understanding what happens when something goes wrong. Correct representational exceptions allows immediately understand (just having looked at logs) what the problem is. Useful when deploying servers.Features:Allows to DRY import variablesReadability for humansJSON and YAML support out of the box (In fact, additional libraries will be automatically installed for support it)Typing or validation of all importing data. And this isrequiredbecause human factor preventionPython 2.7, 3+ compatible100% code coverageCustom format of configuration files can be used. If I missed and at now anyone uses something else except of supported formats, you can create anissueabout it, and probably the new format will be supported in next versions.For Python data structures validation is used excellent librarykolypto/py-goodFor YAML parsing is used a great lib of Kirill SimonovPyYAMLQuick startJust look at the code.fromkonfimportKonf# Filling of variables from config file tokens.yaml in k_ objectk_=Konf('tokens.yaml')# Getting variables from k_: first argument is a name of variable (specified in the config),# second can be a type or validatorSECRET_KEY=k_('secret_key',basestring)AUTH_TOKEN=k_('auth_token',basestring)# In the next example is used a validator: list, that must contain# only objects with basestring type (str or unicode)CLIENTS=k_('clients',[basestring])# And dict with two required keys with appropriate typesDELAYS=k_('delays',{'case1':int,'case2':int})You can find more details and advanced examples about natural validation ongoodpageOk, what happened next? Imagine that tokens.yaml is missing. In case of this, after the script execution, we can see next exception message:konf.main.ReadError: Can`t access to the configuration file "tokens.yaml"Let’s create a file tokens.yaml and input next:---secret_key:FOOauth_token:BARclients:Q,delays:case1:15case2:17Exception is raised:Traceback (most recent call last):File"/Users/me/python/examples/example.py", line19, in<module>CLIENTS=k_('clients',[basestring])File"/Users/me/python/examples/konf/konf/main.py", line126, in__call__raiseself.ValidationError(e)konf.main.ValidationError:expected a listThen fix this mistake:---secret_key:FOOauth_token:BARclients:[Q]delays:case1:15case2:17Now all be OK, because[Q]represents a list of values, not a string.Note: you can see the list of all supported exceptions in the end of this documentation page.Default valuesDo you need to use a value if any variable is not contained in a config file? You can use default value.fromkonfimportKonfk_=Konf('extra.yml')# 3rd arg is a default. If variable STRICT is not contained in config file,# USE_STRICT will be FalseUSE_STRICT=k_('STRICT',bool,False)# You can also use None as default valueWINNER=k_('WINNER',int,None)# Default values will never be validated, because you forcibly declaring it.# So, the next example is legit.SHIFT_TIME=k_('SHIFT',int,complex(42,42))Checking redundant variablesSometimes you want to be sure that all of the variables in a config file are used and you haven’t forgotten anything.
In this situation thecheck_redundant()method can be helpful.fromkonfimportKonfk_=Konf('bar.yaml')FOO1=k_('foo1',int)FOO2=k_('foo2',int)# If config file contains anything except foo1 and foo2,# RedundantConfigError will be raised after call of this method!k_.check_redundant()# FailDefault values andcheck_redundant()also working fine together.fromkonfimportKonfk_=Konf('foo.yaml')X=k_('X',int,0)Y=k_('Y',int,0)# If X and Y doesn't contained in the config file, RedundantConfigError will not be raised# after next line of code, because they have default values.# So, it's just like X == 0 and Y == 0k_.check_redundant()# SuccessMore complex exampleWrite the content to a social_auth.yml in a readable form:---SN:vk:key:'123'secret:qwertygoogle:key:'456'secret:uioptwitter:key:'789'secret:zxcok:key:'000'secret:vbnpublic_name:mStep-by-step process it in settings.py# 0. Select configuration filek_=Konf('social_auth.yml')# 1. Declare validators# You can cache validators inside a Konf object as if it's a standard python dictk_['v1']={'key':basestring,'secret':basestring,}k_['v2']={'key':basestring,'secret':basestring,'public_name':basestring}# 2. Get variables from config# For avoid copy-paste and massive chunks of code, just declare a new variable# and pass data from config to itsn=k_('SN',{'vk':k_['v1'],# You can choose validator you want, for example v1...'google':k_['v1'],'twitter':k_['v1'],'ok':k_['v2']# ...or v2})# 3. Fill everything to a python variables which are required for 3rd-party librarySOCIAL_AUTH_VK_OAUTH2_KEY=sn['vk']['key']SOCIAL_AUTH_VK_OAUTH2_SECRET=sn['vk']['secret']SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=sn['google']['key']SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=sn['google']['secret']SOCIAL_AUTH_TWITTER_KEY=sn['twitter']['key']SOCIAL_AUTH_TWITTER_SECRET=sn['twitter']['secret']SOCIAL_AUTH_ODNOKLASSNIKI_KEY=sn['ok']['key']SOCIAL_AUTH_ODNOKLASSNIKI_SECRET=sn['ok']['secret']SOCIAL_AUTH_ODNOKLASSNIKI_OAUTH2_PUBLIC_NAME=sn['ok']['public_name']# 4. Check that config doesn't contain some garbage# (this might mean you forgot to get these variables, or this config is wrong, some draft for example)k_.check_redundant()# 5. If server is running without errors, and you will meet issue with this 3rd-party library later,# you can be sure that problem isn't in your configuration file.# Otherwise, you'll just catch a error on a start server stage.List of supported ExceptionsExceptionRaises when…ValidationErrorData from config file doesn’t match to thetype_or_validatorargIncompleteConfigErrorTrying to get variable that not contained in a config fileReadErrorConfig file can’t be readParseErrorThird-party parser can’t parse configuration fileReassignmentErrorVariable is loaded not for the first timeFileExtensionErrorExtension of the config isn’t supported, andparse_callbackarg isn’t specifiedRedundantConfigErrorCall ofcheck_redundant()if any of variables in a config isn’t used in appValidatorManagementErrorIncorrect usage of validators