Getting started

Install AClick from PyPI by running:

pip install aclick

From Click to AClick

AClick is a wrapper library around click and provides the command() and group() decorators as well as Command and Group classes. The decorators will automatically register aclick types and if you supply your own Command or Group implementation, they will wrap it as an aclick type.

Similarly to Click, decorating a function with click.command() will make it into a callable script. However, with aclick we do not need to specify parameter types, defaults and help, but everything is parsed automatically from type annotations and docstring:

# Click example
import click

@click.command()
@click.argument('name')
@click.option('--age',
    default=18, type=int,
    help='Your age')
def hello(name, age):
    '''
    Prints greeting
    '''


    click.echo(f'Hello {name}!')
# AClick example
import aclick, click





@aclick.command()
def hello(name: str, /, age: int = 18):
    '''
    Prints greeting

    :param age: Your age
    '''
    click.echo(f'Hello {name} with age {age}!')

In both cases the resulting Command can be invoked:

if __name__ == '__main__':
    hello()

And what it looks like:

$ python hello.py Jonas --age 25
Hello Jonas with age 25!

And the corresponding help page:

$ python hello.py --help
Usage: hello.py [OPTIONS] NAME

  Prints greeting

Options:
  --help         Show this message and exit.
  --age INTEGER  Your age  [default: 18]

Supported types

By default, aclick supports the following types:

In hierarchical parsing, there are some restrictions on supported types. Please refer to hierarchical parsing section.

Arguments and options

All positional arguments are expanded as Click’s arguments and keyword arguments are expanded as options. In the following example, name will become an argument and age will became an option.

@aclick.command()
def hello(name: str, /, age: int = 18):
    click.echo(f'Hello {name} with age {age}!')
$ python hello.py --help
Usage: hello.py [OPTIONS] NAME

Options:
  --help         Show this message and exit.
  --age INTEGER  [default: 18]

Command groups

Similarly to the Command example, by importing the group decorator from aclick all commands will be of class Command and they will automatically parse function’s parameters.

# Click example
@click.group()
def cli():
    pass

@cli.command()
@click.option('--user', type=str)
def initdb(user: str):
    click.echo(f'{user} initialized the database')

@cli.command()
@click.option('--database', type=str)
def dropdb(database):
    click.echo(f'Dropped the database: {database}')
# AClick example
@aclick.group()
def cli():
    pass


@cli.command()
def initdb(user: str):
    click.echo(f'{user} initialized the database')


@cli.command()
def dropdb(database: str):
    click.echo(f'Dropped the database: {database}')

The cli group is then used as the entrypoint:

if __name__ == '__main__':
    cli()

Lists and Dictionaries

Lists and dictionaries can be uses as parameters in aclick. For the dictionaries, the key has to be a string. The values contained in the list or dictionary can be any basic type like str, float, bool, int, but it can also be a complex structure of classes, see inline types. See also container types. We will demonstrate the usage in the following example.

@dataclass
class Person:
    name: str


@aclick.command
def main(list: t.List[Person], age: t.Dict[str, int]):
    for p in list:
        p_age = age[p.name]
        print(f'    {p.name} is {p_age} years old')

Which we can call as follows:

$ python main.py --list 'person(Alice),person(Bob)' --age Alice=21,Bob=53
    Alice is 21 years old
    Bob is 53 years old