Configuration

12-factor interactive self-building lazy configuration.

The developer story we are after:

  • there’s nothing to do, just expect cli2.cfg['YOUR_ENV_VAR'] to work one way or another

  • when there’s a minute to be nice to the user, add some help that will be displayed to them: cli2.cfg.questions['YOUR_ENV_VAR'] = 'this is a help text that will be display to the user when we prompt them for YOUR_ENV_VAR'

This is the user story we are after:

  • user runs your cli2 command right after install without any configuration

  • the user is prompted for a variable

  • the variable is saved in their ~/.profile in a new export line

  • the user runs a command again in the same shell: we should find the variable in ~/.profile so he doesn’t have to start a new shell for his new configuration to work

Of course, if the environment variable is already present in the environment then this basically returns it from os.environ.

class cli2.configuration.Configuration(profile_path=None, **questions)[source]

Configuration object.

Wraps around environment variable and can question the user for missing variables and save them in his shell profile.

questions

A dict of ENV_VAR=question_string, if an env var is missing from configuration then question_string will be used as text to prompt the user.

profile_path

Path to the shell profile to save/read variables, defaults to ~/.profile which should work in many shells.

You can also just work with the module level (“singleton”) instance, have scripts like:

import cli2

cli = cli2.Group()

cli2.cfg['API_URL'] = 'What is your API URL?'

@cli.cmd
def foo():
    api_url = cli2.cfg['API_URL']

    # when there's no question, it'll use the var name as prompt
    api_url = cli2.cfg['USERNAME']
configure(key)[source]

Core logic to figure a variable.

  • if present in os.environ: return that

  • if parsed in profile_variables: return that

  • otherwise prompt it, with the question if any, then save it to profile_path

delete(key, reason=None)[source]

Delete a variable from everywhere, useful if an api key expired.

Parameters:
  • key – Env var name to delete

  • reason – Reason to print to the user

input(prompt)[source]

Wraps around Python’s input but adds confirmation.

Parameters:

prompt – Prompt text to display.

property profile_script

Cached profile_path reader.

property profile_variables

Cached environment variable parsing from profile_path.

Example

import cli2

cli2.cfg.questions['FOO'] = 'What is your FOO?'

print(f'Foo={cli2.cfg["FOO"]}')
print(f'Bar={cli2.cfg["BAR"]}')

Session:

$ python cli2/examples/conf.py
What is your FOO?
> dunno

Confirm value of:
dunno
(Y/n) >
Appended to /home/jpic/.profile:
export FOO=dunno
Foo=dunno

BAR
> woot?

Confirm value of:
woot?
(Y/n) >y
Appended to /home/jpic/.profile:
export BAR='woot?'
Bar=woot?

$ python cli2/examples/conf.py
Foo=dunno
Bar=woot?