Skip to main content

A minimal and ridiculously good looking command-line-interface toolkit.

Project description

Proper CLI

Proper CLI is a Python package for creating beautiful, composable, and ridiculously good looking command-line-user-interfaces without having to write any extra code.

  • Made for interfacing with humans.
  • Arbitrary nesting and composition of commands.
  • Automatic help page generation.
  • No need to redeclare paramaters and options with decorators, just write Python methods.
  • The help of a command is its docstring.

Usage

Declare a class that inherits from proper_cli.Cli. Every method/attribute that does not starts with an underscore will be a command.

from proper_cli import Cli

class Manage(Cli):
    def first(self, arg1, arg2=3):
        pass

    def second(self):
        pass

    def _not_a_command(self):
        pass

Then, instance that class and call it.

# run.py
cli = Manage()

if __name__ == "__main__":
    cli()

The class dosctring will be printed at the beginning of the help page.

The arguments can be then passed by position:

python run.py first foo bar

or by name:

python run.py first -arg1 foo -arg2 bar

To pass a True use the name without a value, for a False, prepend the name of the argument with no-:

python run.py first -arg1 -no-arg2

Subcommands

If an attribute is a subclass of proper_cli.Cli, it will be a subcommand:

from proper_cli import Cli

class DBSub(Cli):
    def migrate(self):
        pass

class Manage(Cli):
    # A subcommand
    db = DBSub  # NOT `DBSub()`

Context

You can pass any named argument as context to be used by your commands. This will be stored at the _env attribute.

Example:

>>> cli = Manage(lorem="ipsum")
>>> print(cli._env)
{"lorem": "ipsum"}

An example

proper_cli output

This autogenerated help message is the result of running the example below:

# example.py
from proper_cli import Cli


class DBCli(Cli):
    """Database-related commands
    """

    def migrate(self, message):
        """Autogenerate a new revision file.

        This is an alias for "revision --autogenerate".

        Arguments:

        - message: Revision message

        """
        pass

    def branches(self):
        """Show all branches."""
        pass


class MyCli(Cli):
    """Welcome to Proper CLI 3
    """

    def new(self, path, quiet=False):
        """Creates a new Proper application at `path`.

        Arguments:

        - path: Where to create the new application.
        - quiet [False]: Supress all output.
        """
        pass

    def hello(count, name):
        """Simple program that greets NAME for a total of COUNT times."""
        pass

    # A subcommand!
    db = DBCli


cli = MyCli()

if __name__ == "__main__":
    cli()

Coloring the Output

Whenever you output text, you can surround the text with tags to color its output. This is automatically enabled for the docstrings, but you can also have it by using proper_cli.echo() as a drop-in replacement of print().

# green text
echo("<fg=green>foo</fg=green>")

# black text on a cyan background
echo("<fg=black;bg=cyan>foo</>")

# bold text on a yellow background
echo("<bg=yellow;options=bold>foo</>")

Available foreground and background colors are: black, red, green, yellow, blue, magenta, cyan and white.

The available options are: bold, underscore, blink, reverse and conceal.

The closing tag can be replaced by </>, which revokes all formatting options established by the last opened tag.

Custom styles

These four styles are available by default:

# green text
echo("<info>foo</info>")

# yellow text
echo("<comment>foo</comment>")

# black text on a cyan background
echo("<question>foo</question>")

# white text on a red background
echo("<error>foo</error>")

It is possible to define your own styles using the proper_cli.add_style() method:

add_style("fire", fg="red", bg="yellow", options=["bold", "blink"])
echo("<fire>foo</fire>")

Helpers

Beyond the CLI builder, proper_cli also includes some commonly-used helper functions

confirm(question, default=False, yes_choices=YES_CHOICES, no_choices=NO_CHOICES)

Ask a yes/no question via and return their answer.

ask(question, default=None, alternatives=None)

Ask a question via input() and return their answer.

FAQ

Why don't just use optparse or argparse?

I find it too verbose.

Why don't just use click?

Are you kidding? Because this looks better and is easier to use and understand.

Why don't just use...?

Because this library fits better my mental model. I hope it matches yours as well.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proper-cli-1.1.1.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

proper_cli-1.1.1-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file proper-cli-1.1.1.tar.gz.

File metadata

  • Download URL: proper-cli-1.1.1.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for proper-cli-1.1.1.tar.gz
Algorithm Hash digest
SHA256 afbd01d78fd95317826c35e9c8baaac664a05d6b877a4b33413f09946d97c0c6
MD5 fea2722b98ed2cc3dd5d503e4cbeae39
BLAKE2b-256 0d6f203617fdb80196ca9bea070b9c3b61c7b54dc377abbef6b10b61df73ba4a

See more details on using hashes here.

File details

Details for the file proper_cli-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: proper_cli-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for proper_cli-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5c827074df02e9b19891db13da9973cea01a7a866815b260deaa6615f29baa97
MD5 e5bbc23a4e885e54c0729c5afbd241e8
BLAKE2b-256 bc60363ba083f1fac471a441fda86a84b3d068108bcc8d3bb1d4db140db38518

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page