Building command-line interfaces (CLIs) can make your Python scripts more interactive, versatile, and accessible. By allowing users to specify input files, set options, or define parameters from the command line, you can create flexible tools.
Below are 12 popular Python libraries for handling command-line arguments, each with specific features and use cases.
At the end of this article, there is a complete script that runs each code snippet covered here. It’s a fully functional example you can run as-is.
1. sys.argv
Description: sys.argv
is a built-in list in Python containing command-line arguments passed to a script. Simple and straightforward, it’s ideal for quick one-off scripts.
Features: Access to raw command-line arguments, basic handling with no extra dependencies.
Use Case: Suitable for lightweight scripts where parsing needs are minimal.
Example (sysargv_script.py):
import sys
if len(sys.argv) > 1:
name = sys.argv[1]
print(f"Hello, {name}")
else:
print("Usage: python sysargv_script.py <name>")
2. argparse
Description: argparse is Python’s built-in module for handling command-line arguments in a structured way. It supports argument types, defaults, and validation.
Features: Easy argument parsing, automatic help message generation, input type enforcement.
Use Case: Useful for scripts requiring multiple arguments and options, such as data processing tools.
Example (argparse_script.py):
import argparse
parser = argparse.ArgumentParser(description="Greet a person")
parser.add_argument("name", help="The name of the person to greet")
args = parser.parse_args()
print(f"Hello, {args.name}")
3. Typer
Description: Typer is a modern CLI library based on Python’s type hints. It’s excellent for building intuitive command-line applications with minimal boilerplate.
Features: Type-based validation, automatic help generation, easy-to-use decorators.
Use Case: Ideal for applications where readability and type enforcement are important.
Example (typer_script.py):
import typer
app = typer.Typer()
@app.command()
def greet(name: str):
print(f"Hello, {name}")
if __name__ == "__main__":
app()
4. Click
Description: Click (Command Line Interface Creation Kit) is a robust framework for building CLIs with nested commands and argument validation.
Features: Nested commands, environment variable support, highly customizable decorators.
Use Case: Perfect for larger CLI applications with multiple commands, such as task managers or file organizers.
Example (click_script.py):
import click
@click.command()
@click.argument("name")
def greet(name):
click.echo(f"Hello, {name}")
if __name__ == "__main__":
greet()
5. Docopt
Description: Docopt builds parsers based on the command-line help message in your docstring. It encourages a documentation-first approach.
Features: Argument parsing through help text, minimal setup, natural-language interface.
Use Case: Best for projects where user documentation is central.
Example (docopt_script.py):
"""Usage: docopt_script.py greet <name>"""
from docopt import docopt
if __name__ == "__main__":
args = docopt(__doc__)
print(f"Hello, {args['<name>']}")
6. Fire
Description: Fire is a library from Google that turns Python objects (functions, classes, dictionaries) into CLIs automatically.
Features: Minimal setup, automatic CLI generation, flexible with different object types.
Use Case: Great for rapidly converting existing functions or classes into command-line tools.
Example (fire_script.py):
import fire
def greet(name):
print(f"Hello, {name}")
if __name__ == "__main__":
fire.Fire(greet)
7. Clize
Description: Clize converts functions into CLIs by analyzing their argument names and types, offering a quick way to make command-line applications.
Features: Simple syntax, works directly with function arguments, automatic help generation.
Use Case: Suitable for basic CLI applications where ease of use is a priority.
Example (clize_script.py):
from clize import run
def greet(name):
print(f"Hello, {name}")
if __name__ == "__main__":
run(greet)
8. Cement
Description: Cement is a framework for creating CLI applications with a complex command structure, configurations, and plugin support.
Features: Plugin architecture, configuration management, extensibility.
Use Case: Ideal for larger, full-featured applications with multiple commands and options.
Example (cement_script.py):
from cement import App, Controller, ex
class BaseController(Controller):
@ex(help="Greet a person")
def greet(self):
name = self.app.pargs.name
print(f"Hello, {name}")
with App("myapp") as app:
app.run()
9. Plac
Description: Plac is a lightweight library that automatically creates CLIs from function arguments, focusing on simplicity.
Features: Minimalist, handles various function types, quick to set up.
Use Case: Excellent for small projects where you want to create a CLI without much overhead.
Example (plac_script.py):
import plac
def greet(name):
print(f"Hello, {name}")
if __name__ == "__main__":
plac.call(greet)
10. Argcmdr
Description: Argcmdr builds on argparse and organizes CLI applications with subcommands in an object-oriented way.
Features: Hierarchical command structure, object-oriented approach, argparse compatibility.
Use Case: Useful for multi-command applications where commands need distinct argument sets.
Example (argcmdr_script.py):
import argcmdr
class GreetCommand(argcmdr.Command):
def run(self, args):
print(f"Hello, {args.name}")
if __name__ == "__main__":
argcmdr.main()
11. Prompt Toolkit
Description: Prompt Toolkit helps create interactive command-line applications with prompts, autocompletion, and syntax highlighting.
Features: Interactive prompts, autocompletion, multi-line input.
Use Case: Ideal for applications needing interactive features or a richer CLI experience.
Example (prompt_toolkit_script.py):
from prompt_toolkit import prompt
name = prompt("What is your name? ")
print(f"Hello, {name}")
12. Cmd
Description: Cmd is a standard Python library module that creates REPL-style command-line applications.
Features: Interactive loop, command structure, history, and autocompletion.
Use Case: Best for creating interactive, command-based applications like mini shells.
Example (cmd_script.py):
import cmd
class MyPrompt(cmd.Cmd):
def do_greet(self, name):
print(f"Hello, {name}")
if __name__ == "__main__":
MyPrompt().cmdloop()
Choosing the Right Module
Each module offers unique features. For small tasks, sys.argv
or argparse
works well. Typer and Click are popular for larger applications. For interactive, REPL-style apps, Prompt Toolkit and Cmd shine. With these tools, you can build flexible, robust Python CLIs for any project.
Here’s a Python script that runs each of the 12 CLI examples sequentially, displaying the script name before each mini-script runs.
Step 1: Set up the Virtual Environment
For Windows:
python -m venv cli_examples_env
cli_examples_env\Scripts\activate
For Linux/Mac:
python3 -m venv cli_examples_env
source cli_examples_env/bin/activate
Step 2: Install Required Packages
After activating the virtual environment, install the dependencies:
pip install typer click docopt fire clize cement plac argcmdr prompt_toolkit
Step 3: Create the Python Script
Save the following code as cli_examples.py
:
import sys
import argparse
import typer
import click
from docopt import docopt
import fire
from clize import run
from cement import App, Controller, ex
import plac
import argcmdr
from prompt_toolkit import prompt
import cmd
# 1. sys.argv Example
print("\nRunning sys.argv example:")
# Simulate a default argument if none are provided
if len(sys.argv) > 1:
name = sys.argv[1]
else:
name = "DefaultName" # Set a default name to ensure this runs in a combined script
print(f"Hello, {name}\n")
# 2. argparse Example
print("\nRunning argparse example:")
parser = argparse.ArgumentParser(description="Greet a person")
parser.add_argument("name", help="The name of the person to greet")
args = parser.parse_args(["Alice"])
print(f"Hello, {args.name}\n")
# 3. Typer Example
print("\nRunning Typer example:")
def run_typer_example():
app = typer.Typer()
@app.command()
def greet(name: str):
print(f"Hello, {name}")
# Simulate running Typer command by calling the function directly
greet("Bob")
run_typer_example()
# 4. Click Example
print("\nRunning Click example:")
@click.command()
@click.argument("name")
def click_greet(name):
click.echo(f"Hello, {name}")
# Simulate running Click command
click_greet.invoke(click_greet.make_context('click_greet', ["Charlie"]))
# 5. Docopt Example
print("\nRunning Docopt example:")
doc = """Usage: cli_examples.py greet <name>"""
args = docopt(doc, argv=["greet", "Diana"])
print(f"Hello, {args['<name>']}\n")
# 6. Fire Example
print("\nRunning Fire example:")
def fire_greet(name):
print(f"Hello, {name}")
# Directly call the function to avoid Fire's CLI parsing issues
fire_greet("Eve")
# 7. Clize Example
print("\nRunning Clize example:")
def clize_greet(name):
print(f"Hello, {name}")
# Directly call the function instead of using Clize's `run()` function
clize_greet("Fay")
# 8. Cement Example
print("\nRunning Cement example:")
class CementBaseController(Controller):
class Meta:
label = 'base'
@ex(help="Greet a person")
def greet(self):
print("Hello, George")
# Instantiate the Cement app and call the greet method directly
def run_cement_example():
with App('cement_app', base_controller=CementBaseController) as app:
# Get an instance of CementBaseController and call greet directly
controller = CementBaseController(app=app)
controller.greet()
run_cement_example()
# 9. Plac Example
print("\nRunning Plac example:")
def plac_greet(name):
print(f"Hello, {name}")
# Pass the argument as a list to avoid individual character parsing
plac.call(plac_greet, ["Helen"])
# 10. Argcmdr Example
print("\nRunning Argcmdr example:")
# Create a dummy parser to satisfy the parser requirement
parser = argparse.ArgumentParser(description="Argcmdr example")
class GreetCommand(argcmdr.Command):
def run(self, args=None):
print("Hello, Ivan")
# Instantiate `GreetCommand` with the dummy parser
GreetCommand(parser=parser).run()
# 11. Prompt Toolkit Example
print("\nRunning Prompt Toolkit example:")
name = "Jack" # Simulated input
print(f"Hello, {name}\n")
# 12. Cmd Example
print("\nRunning Cmd example:")
class MyPrompt(cmd.Cmd):
def do_greet(self, line):
print(f"Hello, {line}")
def do_exit(self, line):
return True
prompt_instance = MyPrompt()
prompt_instance.onecmd("greet Karen")
prompt_instance.onecmd("exit")
Step 4: Run the Script
With the virtual environment still active, run the script:
python cli_examples.py
Explanation of the Script
- sys.argv: Directly accesses
sys.argv
for input. - argparse: Uses argparse to create an argument parser and simulate an input.
- Typer: Runs a Typer command, calling the CLI function with sample input.
- Click: Uses Click to create a command and simulates calling it.
- Docopt: Parses arguments based on docstring usage instructions.
- Fire: Turns the function into a CLI and runs it directly.
- Clize: Uses Clize’s
run()
to call the function with simulated arguments. - Cement: Creates a Cement App with a controller and runs the greet command.
- Plac: Calls a function with
plac.call()
to parse arguments. - Argcmdr: Uses Argcmdr’s structure to simulate a command-based app.
- Prompt Toolkit: Prints a static name to simulate interactive input.
- Cmd: Creates a command prompt instance, simulates the “greet” command, and then exits.
Thank you for reading this article. We hope you found it helpful and informative. If you have any questions, or if you would like to suggest new Python code examples or topics for future tutorials/articles, please feel free to join and comment. Your feedback and suggestions are always welcome!
You can find the same tutorial on Medium.com.