项目作者: cidrblock

项目描述 :
Modelsettings is a straight-forward, easy to use python application settings manager that includes ini file, environment variable, and command-line parameter support.
高级语言: Python
项目地址: git://github.com/cidrblock/modelsettings.git
创建时间: 2018-03-22T16:29:34Z
项目社区:https://github.com/cidrblock/modelsettings

开源协议:MIT License

下载


Build Status

Model Settings

Overview

Modelsettings is a straight-forward, easy to use python application settings manager that includes ini file, environment variable, and command-line parameter support.

The necessary settings variables are declared in a yaml model, which is then used to parse an .ini file, environment variables, and finally command-line arguments.

In addition to reading settings from the three sources, modelsettings also includes sample configuration generator support for:

  • command-line
  • environment variables (e.g., export statements)
  • ini file
  • docker run
  • docker compose
  • kubernetes
  • drone plugins

Quick start

Build the model

Modelsettings looks for a model_settings.yml in the current working directory. A simple model_settings.yml file might look like this:

  1. env_prefix: CF
  2. model:
  3. cream:
  4. choices:
  5. - True
  6. - False
  7. default: False
  8. example: True
  9. help: Would you like cream in your coffee?
  10. required: True
  11. sugar:
  12. choices:
  13. - True
  14. - False
  15. default: True
  16. example: True
  17. help: Would you like sugar in your coffee?
  18. required: True
  19. size:
  20. choices:
  21. - 10
  22. - 12
  23. - 16
  24. default: 12
  25. example: 16
  26. help: What size cup would you like in ounces?
  27. required: True

env_prefix is used as a prefix for the environment variables, this helps avoid name collision when running multiple python applications in the same shell.

model is a dictionary of required settings values.

Import and use the module

In your application, simply import modelsettings.

  1. $ python3 -m venv venv
  2. $ source venv/bin/activate
  3. $ pip install modelsettings

app.py

  1. from modelsettings import settings
  2. def main():
  3. output = f"You ordered a {settings.SIZE} oz. cup of coffee"
  4. modifiers = []
  5. if settings.CREAM: modifiers.append("cream")
  6. if settings.SUGAR: modifiers.append("sugar")
  7. if modifiers:
  8. output += " with " + " and ".join(modifiers)
  9. output += "."
  10. print(output)
  11. if __name__ == "__main__":
  12. main()

All settings are converted to uppercase and available as settings.XXXXX

Additional command-line parameters

--help

Argparse help is generated from the model:

  1. $ python app.py --help
  2. usage: app.py [-h]
  3. [--generate {command,docker-run,docker-compose,ini,env,kubernetes,readme,drone-plugin}]
  4. [--settings SETTINGS] [--cream {True,False}]
  5. [--sugar {True,False}] [--size {10,12,16}]
  6. optional arguments:
  7. -h, --help show this help message and exit
  8. --generate {command,docker-run,docker-compose,ini,env,kubernetes,readme,drone-plugin}
  9. Generate a template
  10. --settings SETTINGS Specify a settings file. (ie settings.dev)
  11. --cream {True,False} Would you like cream in your coffee? e.g., True
  12. --sugar {True,False} Would you like sugar in your coffee? e.g., True
  13. --size {10,12,16} What size cup would you like in ounces? e.g., 16

--generate

A command-line parameter of generate is added to the application which, when used, will generate sample settings in a number of formats.

  1. $ python app.py --generate env
  2. export CF_CREAM=True
  3. export CF_SIZE=16
  4. export CF_SUGAR=True

--generate readme

Markdown can be generated which includes all the available generate formats.

  1. $ python app.py --generate readme >> README.md

Order of operations

The .ini file is read first, then the environment variables, then the command-line parameters.

.ini file support

The application will now support loading settings from a settings.ini file.

  1. $ cat settings.ini
  2. [settings]
  3. cream=True
  4. size=16
  5. sugar=True
  6. $ python app.py
  7. You ordered a 16 oz. cup of coffee with cream and sugar.

An alternate settings file can be specified with the command line, this is useful during development of the application.

  1. $ cat settings.dev
  2. [settings]
  3. cream=True
  4. size=10
  5. sugar=False
  6. $ python app.py --settings settings.dev
  7. You ordered a 10 oz. cup of coffee with cream.
  8. $ python app.py --settings settings.dev --size 16
  9. You ordered a 16 oz. cup of coffee with cream.

Environment variable support

All settings can be stored as environment variables. The environment variables should be prefaced with the env_prefix from the model_settings.yml file and capitalized.

  1. $ export CF_CREAM=False
  2. $ export CF_SIZE=12
  3. $ export CF_SUGAR=True
  4. $ python app.py
  5. You ordered a 12 oz. cup of coffee with sugar.
  6. $ export CF_CREAM=True
  7. $ python app.py
  8. You ordered a 12 oz. cup of coffee with cream and sugar.

Command-line parameter support

Command line parameters take precedence over .ini files and environment variables.

  1. $ python app.py --size 10 --sugar False --cream False
  2. You ordered a 10 oz. cup of coffee.
  3. $ python app.py --size 12 --sugar True --cream False
  4. You ordered a 12 oz. cup of coffee with sugar.
  5. $ python app.py --size 16 --sugar True --cream True
  6. You ordered a 16 oz. cup of coffee with cream and sugar.

model_settings.yml

1) The model support 5 basic python types:

  • bool
  • int
  • float
  • string
  • list
  • dict

The type is derived from the example given, and the settings variable is cast to that type.

In the example below, each supported type is shown with a corresponding yaml native example.

example is therefore a required property for every entry in the model.

  1. bool:
  2. choices:
  3. - True
  4. - False
  5. default: False
  6. help: This is an integer setting
  7. required: False
  8. example: True
  9. integer:
  10. choices:
  11. - 10
  12. - 20
  13. default: 60
  14. help: This is an integer setting
  15. required: False
  16. example: 30
  17. float:
  18. default: 60.5
  19. help: This is an integer setting
  20. required: False
  21. example: 30.5
  22. string:
  23. default: string
  24. help: This is a string setting
  25. required: False
  26. example: string
  27. dictionary:
  28. default:
  29. key: value
  30. help: This is a dict setting
  31. required: False
  32. example:
  33. key: value
  34. list:
  35. default:
  36. - item1
  37. - item2
  38. help: This is a list setting
  39. required: False
  40. example:
  41. - item1
  42. - item2

Dictionaries and lists objects in .ini and environment variables.

Dictionary and lists should be represented as json in .ini files and environment variables:

  1. $ more complex.yml
  2. env_prefix: RM
  3. model:
  4. dictionary:
  5. default:
  6. key: value
  7. help: This is a dict setting
  8. required: False
  9. example:
  10. key: value
  11. list:
  12. default:
  13. - item1
  14. - item2
  15. help: This is a list setting
  16. required: False
  17. example:
  18. - item1
  19. - item2
  20. $ export MODEL_SETTINGS=complex.yml
  21. $ python app.py --generate env
  22. export RM_DICTIONARY='{"key": "value"}'
  23. export RM_LIST='["item1", "item2"]'
  24. $ python app.py --generate ini
  25. [settings]
  26. dictionary={"key": "value"}
  27. list=["item1", "item2"]

Docker

Because all settings are supported as environment variables, transitioning a python application to a docker container is simple.

Dockerfile

  1. FROM python:3.6.4-alpine
  2. RUN apk add -U \
  3. ca-certificates \
  4. && rm -rf /var/cache/apk/* \
  5. && pip install --no-cache-dir --upgrade pip
  6. WORKDIR /usr/src/app/
  7. ADD model_settings.yml .
  8. ADD app.py .
  9. ADD requirements.txt .
  10. RUN pip install -r requirements.txt
  11. ENTRYPOINT ["python", "app.py"]

Build

  1. $ docker build -t coffee .
  2. <...>
  3. Successfully built 74938ac5902a
  4. Successfully tagged coffee:latest

Generate

  1. $ python app.py --generate docker-run
  2. docker run -it \
  3. -e CF_CREAM=True \
  4. -e CF_SIZE=16 \
  5. -e CF_SUGAR=True \
  6. <container-name>

Run

  1. $ docker run -it \
  2. -e CF_CREAM=True \
  3. -e CF_SIZE=16 \
  4. -e CF_SUGAR=True \
  5. coffee
  6. You ordered a 16 oz. cup of coffee with cream and sugar.
  7. $ docker run -it \
  8. -e CF_CREAM=False \
  9. -e CF_SIZE=12 \
  10. -e CF_SUGAR=True \
  11. coffee
  12. You ordered a 12 oz. cup of coffee with sugar.