cli2 Python API Documentation¶
Command¶
- class cli2.command.Command(target, *args, **kwargs)[source]¶
Represents a command bound to a target callable.
- arg(name, *, kind: str = None, position: int = None, doc=None, color=None, default, annotation)[source]¶
Inject new
Argument
into this command.The new argument will appear in documentation, but won’t be bound to the callable: it will only be avalaible in self.
For example, you are deleting an “http_client” argument in
setargs()
so that it doesn’t appear to the CLI user, to whom you want to expose a couple of arguments such as “base_url” and “ssl_verify” that you are adding programatically with this method, so that you can use self[‘base_url’].value and self[‘ssl_verify’].value in to generate a “http_client” argument incall()
.The tutorial has a more comprehensive example in the “CLI only arguments” section.
- Parameters:
name – Name of the argument to add
kind – Name of the inspect parameter kind
position – Position of the argument in the CLI
doc – Documentation for the argument
color – Color of the argument
default – Default value for the argument
annotation – Type of argument
- items(factories=False)[source]¶
Return ordered items.
- Parameters:
factories – Show only arguments with factory.
- keys(factories=False)[source]¶
Return ordered keys.
- Parameters:
factories – Show only arguments with factory.
Group¶
- class cli2.group.Group(name=None, doc=None, color=None, posix=False, overrides=None, outfile=None, cmdclass=None, log=True)[source]¶
Represents a group of named commands.
Argument¶
- class cli2.argument.Argument(cmd, param, doc=None, color=None, factory=None, hide=False, **kwargs)[source]¶
Class representing a bound parameter and command line argument.
- property accepts¶
Return True if this argument still accepts values to bind.
- factory_value()[source]¶
Run the factory function and return the value.
If the factory function takes a cmd argument, it will pass the command object.
If the factory function takes an arg argument, it will pass self.
- property iskw¶
Return True if this argument is not positional.
- property value¶
Return the value bound to this argument.
Decorators¶
Display¶
Generic pretty display utils.
This module defines a print function that’s supposed to be able to pretty-print anything, as well as a pretty diff printer.
- cli2.display.diff(diff, **kwargs)[source]¶
Pretty-print a diff generated by Python’s standard difflib.unified_diff method.
# pretty print a diff cli2.diff(difflib.unified_diff(old, new))
- cli2.display.print(*args, **kwargs)[source]¶
Try to print the
render()
’ed args, pass the kwargs to actual print method.# pretty print some_object cli2.print(some_object)
- cli2.display.render(arg)[source]¶
Try to render arg as yaml.
If the arg has a
.json()
method, it’ll be called. If it is parseable as JSON then it’l be parsed as such. Then, it’ll be dumped as colored YAML.Set the env var FORCE_COLOR to anything to force into printing colors even if terminal is non-interactive (ie. gitlab-ci)
# pretty render some_object print(cli2.render(some_object))
Colors¶
Define a bunch of arbitrary color ANSI color codes.
This module is available in the cli2.c namespace.
Example:
import cli2
print(f'{cli2.c.green2bold}OK{cli2.c.reset}')
See the following for details.
"""
Define a bunch of arbitrary color ANSI color codes.
This module is available in the `cli2.c` namespace.
Example:
.. code-block:: python
import cli2
print(f'{cli2.c.green2bold}OK{cli2.c.reset}')
See the following for details.
"""
colors = dict(
cyan='\u001b[38;5;51m',
cyan1='\u001b[38;5;87m',
cyan2='\u001b[38;5;123m',
cyan3='\u001b[38;5;159m',
blue='\u001b[38;5;33m',
blue1='\u001b[38;5;69m',
blue2='\u001b[38;5;75m',
blue3='\u001b[38;5;81m',
blue4='\u001b[38;5;111m',
blue5='\u001b[38;5;27m',
green='\u001b[38;5;10m',
green1='\u001b[38;5;2m',
green2='\u001b[38;5;46m',
green3='\u001b[38;5;47m',
green4='\u001b[38;5;48m',
green5='\u001b[38;5;118m',
green6='\u001b[38;5;119m',
green7='\u001b[38;5;120m',
purple='\u001b[38;5;5m',
purple1='\u001b[38;5;6m',
purple2='\u001b[38;5;13m',
purple3='\u001b[38;5;164m',
purple4='\u001b[38;5;165m',
purple5='\u001b[38;5;176m',
purple6='\u001b[38;5;145m',
purple7='\u001b[38;5;213m',
purple8='\u001b[38;5;201m',
red='\u001b[38;5;1m',
red1='\u001b[38;5;9m',
red2='\u001b[38;5;196m',
red3='\u001b[38;5;160m',
red4='\u001b[38;5;197m',
red5='\u001b[38;5;198m',
red6='\u001b[38;5;199m',
yellow='\u001b[38;5;226m',
yellow1='\u001b[38;5;227m',
yellow2='\u001b[38;5;226m',
yellow3='\u001b[38;5;229m',
yellow4='\u001b[38;5;220m',
yellow5='\u001b[38;5;230m',
gray='\u001b[38;5;250m',
gray1='\u001b[38;5;251m',
gray2='\u001b[38;5;252m',
gray3='\u001b[38;5;253m',
gray4='\u001b[38;5;254m',
gray5='\u001b[38;5;255m',
gray6='\u001b[38;5;249m',
pink='\u001b[38;5;199m',
pink1='\u001b[38;5;198m',
pink2='\u001b[38;5;197m',
pink3='\u001b[38;5;200m',
pink4='\u001b[38;5;201m',
pink5='\u001b[38;5;207m',
pink6='\u001b[38;5;213m',
orange='\u001b[38;5;202m',
orange1='\u001b[38;5;208m',
orange2='\u001b[38;5;214m',
orange3='\u001b[38;5;220m',
orange4='\u001b[38;5;172m',
orange5='\u001b[38;5;166m',
bold='\033[1m',
reset='\u001b[0m',
)
colors.update({
k + 'bold': v.replace('[', '[1;')
for k, v in colors.items()
})
class Colors:
def __init__(self, colors):
for name, value in colors.items():
setattr(self, name, value)
colors = Colors(colors)
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 anotherwhen 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
.