Package: skeletonkey
SkeletonKey: A Bare-bones Configuration Management Toolskeletonkeyis a simple, lightweight, and flexible configuration management tool that allows you to manage complex configurations for your applications using YAML files. It dynamically loads classes and their arguments at runtime, making it easy to set up and modify your projects.InstallationTo install skeletonkey via pip, run the following command:pipinstallskeletonkeyUsageBelow is an example of how to useskeletonkeyin your project:importskeletonkeyclassMyModel:def__init__(self,layer_size:int,activation:str)->None:self.layer_size=layer_sizeself.activation=activation@skeletonkey.unlock("config.yaml")defmain(args):model=skeletonkey.instantiate(args.model)print("Model layer size: ",model.layer_size)print("Model activation: ",model.activation)print("Number of Epochs: ",args.epochs)if__name__=="__main__":main()To run the example above, create a config.yaml file with the following content:epochs:128model:_target_:main.MyModellayer_size:128activation:reluOverwriting ArgumentsOverwriting default config arguments is easy withskeletonkey.To execute the script and overwrite default arguments, use this command:pythonproject.py--epochs256Moreover, skeletonkey allows you to conveniently work with nested configurations. When dealing with nested arguments in a configuration file, skeletonkey enables you to overwrite default configuration values using dot-separated keys.For instance, if your configuration file has a nested YAML, you can overwrite the default values like this:pythonproject.py--model.parameters.layer_size256The resulting Namespace object will contain nested Namespace objects that can be accessed using dot notation, such as args.model.parameters.layer_size.Defining Flags in ConfigurationFlags can be defined in the configuration YAML file using the?prefix followed by the flag name. The value of the flag is set astrueorfalse. Flags allow a user to switch to debug mode without having to modify the configuration file or temporarily enable/disable specific features for testing without changing the configuration.For example:?debug:trueIn the above example, a flag nameddebugis defined and set totrue.Once defined in the configuration, flags can be overridden using command-line arguments. To override a flag, simply pass the flag name prefixed with--.python your_script.py --debugExecuting the above command will flip the value of thedebugflag. If it was initially set totruein the configuration YAML, it will be changed tofalse, and vice versa.Default Configuration Filesskeletonkeyalso provides the functionality to specify multiple default configuration files at the beginning of the main configuration file. This feature allows you to easily manage and reuse common configurations across different projects or components.Your main configuration file can include default configuration files using either of the following formats:Format 1: Simple Listdefaults:-path\to\yaml_config1.yaml-path\to\yaml_config2.yamlFormat 2: Nested Dictionarydefaults:path:to:-yaml_config1-yaml_config2In both cases,skeletonkeywill automatically merge the default configuration files with the main configuration file, prioritizing the settings in the main configuration file. This means that if there are any conflicts between the default configuration files and the main configuration file, the values in the main configuration file will take precedence.Here's an example of how to use default configuration files in your project:Create two default configuration files:default_config1.yaml:learning_rate:0.001batch_size:64default_config2.yaml:dropout:0.5optimizer:adamIn your mainconfig.yamlfile, include the default configuration files:defaults:-default_config1.yaml-default_config2.yamlepochs:128model:_target_:MyModellayer_size:128activation:reluWhen you run your project,skeletonkeywill merge the default configuration files with the main configuration file, making the values from the default configuration files available in theargsNamespace object:print("Learning rate: ",args.learning_rate)print("Batch size: ",args.batch_size)print("Dropout: ",args.dropout)print("Optimizer: ",args.optimizer)Using Modular Subconfigurationsskeletonkeyintroduces thekeyringfeature, allowing users to modularize their configurations using arbitrary subconfigurations. This feature promotes reusability of common configurations and enhances readability by segregating configurations into logical sub-units.Thekeyringfeature requires users to define akeyringsection in their main configuration file. Within this section, users can reference various subconfigurations that reside in separate files.For example:keyring:models:model1:subconfigs/model.yamlmodel2:subconfigs/model.yamldatasets:mnist:subconfigs/mnist.yamliris:subconfigs/iris.yamlIn the above configuration,model1,model2,mnist, andirisare references to separate subconfigurations that are stored in their respective YAML files under thesubconfigsdirectory. Using theskeletonkey.instantiatemethod, users can create instances of theMyModelclass with the specified parameters from the subconfiguration.Given this setup, here's how you can access values from these subconfigurations in your Python code:@skeletonkey.unlock("config.yaml")defmain(args):model1_config=args.models.model1model2_config=args.models.model2mnist_targets=args.datasets.mnist.num_targetsiris_targets=args.datasets.iris.num_targetsNote: This assumes that num_targets is defined in both the mnist and the iris subconfigs.Using Environment Variables in ConfigurationEnvironment variables can be incorporated in the configuration YAML file by using the$prefix followed by the name of the environment variable. This feature allows the user to store sensitive information, like API keys or database credentials, outside of the configuration file for security reasons. Additionally, a user can use different configurations for development, staging, and production environments by merely setting environment variables.For example:$DATABASE_URL:"default_database_url"In the above example, the configuration will look for an environment variable namedDATABASE_URL. If the environment variable exists, its value will be used; if not, the fallback value"default_database_url"will be utilized.