To build a password generator command line interface (cli) with python, first create a virtual environment and install click. click is a python package for creating command line utility applications. A command line interface application is a software that is run as a command on terminal or command prompt that performs computer operations.
Install click package with pip
$ pip install click
Command line utility
To create the command line interface create a file in your project folder called main.py and type the following code
import click
@click.command()
@click.argument('name')
def main(name):
click.echo(f'Hello {name}')
if __name__ == '__main__':
main()
This code above is a basic usage of click. The two decorators above changes an ordinary python function to command line utility that receives argument and outputs it to console.
@click.command()
The python decorator above turns the function into a command line utility that can be invoked with terminal or command prompt.
@click.argument('name')
The @click.argument
decorator takes in a variable name
as argument. arguments are values passed when the command is invoked in terminal.
$ python main.py Ade
Hello Ade
The argument is 'Ade' which is the name parameter in the main function. The next feature of a command line utility is the ability to pass flags or options. The presence of options in a CLI modify the output of a command. In our main.py
rewrite the main function to include the following.
import click
@click.command()
@click.option('--length', default=8, help='length of password')
@click.option('--digit/--no-digit', default=False, help='include numbers in password')
def main(length, digit):
click.echo(length)
click.echo(digit)
if __name__ == '__main__':
main()
Run the program with the option
$ python main.py --length 10 --digit
10
True
This will output 10 and in case the option is not given the default will be used. The second option is a boolean flag that defaults to False
if it was not used in the command.
@click.option('--length', default=8, help='length of password')
The above decorator allows the command to be invoked with options. Options are parameters of a cli that can change based on the user input. the decorator takes '--length' as an option, with a default value of 8. The default value is used if the option is not specified in the command line.
@click.option('--digit/--no-digit', default=False, help='include numbers in password')
This is a boolean option or flag to include numbers or exclude them when generating our password.
Generating password
Now that we have our command line interface working lets create a function to that will generate a random string of characters. in your main.py add
import random
import string
import click
def generate_password(length, is_digit):
'''This function returns randomly generated string'''
seed = string.ascii_letters
if is_digit: # if the number flag was raised add numbers to the seed
seed += string.digits
return str('').join([random.choice(seed) for i in range(length)])
# ...
generate_password
takes length as an argument and uses it to generate a string of random letters with length of the length variable. To use the function in our cli we just simply call the function passing length as argument.
[random.choice(string.ascii_letters) for i in range(length)]
This is a python list comprehension for generating a list on random ascii letters the size of the length variable.
str('').join([random.choice(string.ascii_letters) for i in range(length)])
The str('').join()
method will combine all the letters in the list into a single string that can be used as a password.
Everything combined together will give:
import random
import string
import click
def generate_password(length, is_digit):
'''This function returns randomly generated string'''
seed = string.ascii_letters
if is_digit:
seed += string.digits
return str('').join([random.choice(seed) for i in range(length)])
@click.command()
@click.option('--length', default=8, help='length of password')
@click.option('--digit/--no-digit', default=False, help='include numbers in password')
def main(length, digit):
password = generate_password(length, digit)
click.echo(f'Password: {password}')
if __name__ == '__main__':
main()
Running the command with the options will give:
$ python main.py --length 16 --digit
Password: C6Cdcvbax5nYcc2d