6.3. OS Commandline Arguments — Python
6.3.1. Alternatives
Check
colorama- coloring terminal output
6.3.2. Typer
Typer is library for building CLI applications that users will love using and developers will love creating. Based on Python 3.6+ type hints.
The key features are:
Intuitive to write: Great editor support. Completion everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.
Easy to use: It's easy to use for the final users. Automatic help, and automatic completion for all shells.
Short: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
Start simple: The simplest example adds only 2 lines of code to your app: 1 import, 1 function call.
Grow large: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.
$ python -m pip install typer
import typer app = typer.Typer() @app.command() def hello(name: str): typer.echo(f"Hello {name}") @app.command() def goodbye(name: str, formal: bool = False): if formal: typer.echo(f"Goodbye Ms. {name}. Have a good day.") else: typer.echo(f"Bye {name}!") if __name__ == "__main__": app()
You have 2 subcommands (the 2 functions): goodbye and hello:
$ python main.py --help Usage: main.py [OPTIONS] COMMAND [ARGS]... Options: --install-completion Install completion for the current shell. --show-completion Show completion for the current shell, to copy it or customize the installation. --help Show this message and exit. Commands: goodbye hello
Now get the --help for hello:
$ python main.py hello --help Usage: main.py hello [OPTIONS] NAME Options: --help Show this message and exit.
And now get the --help for goodbye. Automatic --formal and --no-formal for the bool option:
$ python main.py goodbye --help Usage: main.py goodbye [OPTIONS] NAME Options: --formal / --no-formal --help Show this message and exit.
And if you use it with the hello command:
$ python main.py hello Camila Hello Camila # And with the goodbye command $ python main.py goodbye Camila Bye Camila! # And with --formal $ python main.py goodbye --formal Camila Goodbye Ms. Camila. Have a good day.
6.3.3. docopt
6.3.4. argparse
https://docs.python.org/3/library/argparse.html#the-add-argument-method
Define how a single command-line argument should be parsed.
6.3.5. Parser parameters
prog |
The name of the program (default: |
|---|---|
usage |
A usage message (default: auto-generated from arguments) |
description |
A description of what the program does |
epilog |
Text following the argument descriptions |
parents |
Parsers whose arguments should be copied into this one |
formatter_class |
HelpFormatter class for printing help messages |
prefix_chars |
Characters that prefix optional arguments |
fromfile_prefix_chars |
Characters that prefix files containing additional arguments |
argument_default |
The default value for all arguments |
conflict_handler |
String indicating how to handle conflicts |
add_help |
Add a -h/-help option |
allow_abbrev |
Allow long options to be abbreviated unambiguously |
6.3.6. Argument parameters
parameter |
description |
|---|---|
name or flags |
Either a name or a list of option strings, e.g. foo or |
action |
The basic type of action to be taken when this argument is encountered at the command line |
nargs |
The number of command-line arguments that should be consumed |
const |
A constant value required by some action and nargs selections |
default |
The value produced if the argument is absent from the command line |
type |
The type to which the command-line argument should be converted |
choices |
A container of the allowable values for the argument |
required |
Whether or not the command-line option may be omitted (optionals only) |
help |
A brief description of what the argument does |
metavar |
A name for the argument in usage messages |
dest |
The name of the attribute to be added to the object returned by |
6.3.7. Simple parsing
import argparse parser = argparse.ArgumentParser() parser.add_argument('--numbers', nargs='*', default=[1, 2.5, 3.0], type=float) args = parser.parse_args() print(args) print(args.numbers)
6.3.8. Advanced parameter parsing
import argparse parser = argparse.ArgumentParser( prog='PROGRAM NAME', description='A foo that bars', epilog="And that's how you'd foo a bar") parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') parser.add_argument('--foo', nargs='?', help='foo help') parser.add_argument('--bar', nargs='+', help='bar help') parser.add_argument('--foobar', nargs='*', default=[1, 2, 3], help='BAR!') parser.add_argument('--integers', metavar='int', type=int, choices=range(10), nargs='+', help='an integer in the range 0..9') parser.add_argument('--baz', nargs='?', type=int, default=42, help='the bar to %(prog)s (default: %(default)s)') parser.add_argument('--move', choices=['rock', 'paper', 'scissors']) parser.add_argument('--length', default=10, type=int, required=True) parser.add_argument('--width', default=10.5, type=float) script_arguments = parser.parse_args() print(script_arguments)
6.3.9. File handling
import argparse parser = argparse.ArgumentParser() parser.add_argument('--input', default='input.csv', type=argparse.FileType('r')) parser.add_argument('--output', default='output.c', type=argparse.FileType('w')) args = parser.parse_args() with args.input as input, args.output as output: content = input.read() # do conversion output.write(content)
6.3.10. Examples
import argparse import sys import logging def read(filename): try: with open(filename) as file: return file.read() except FileNotFoundError: logging.critical('File does not exists') sys.exit(127) parser = argparse.ArgumentParser() parser.add_argument('--file', default='/tmp/input.csv', type=read) args = parser.parse_args() print(args)
import argparse parser = argparse.ArgumentParser() parser.add_argument('--file', default='/tmp/input.csv', type=argparse.FileType('r')) try: args = parser.parse_args() except SystemExit: print('File does not exists') print(args)
6.3.11. docopt
"""Naval Fate. Usage: naval_fate.py ship new <name>... naval_fate.py ship <name> move <x> <y> [--speed=<kn>] naval_fate.py ship shoot <x> <y> naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting] naval_fate.py test (true|false) naval_fate.py (-h | --help) naval_fate.py --version Options: -h --help Show this screen. --version Show version. --speed=<kn> Speed in knots [default: 10]. --moored Moored (anchored) mine. --drifting Drifting mine. """ from docopt import docopt if __name__ == '__main__': arguments = docopt(__doc__, version='Naval Fate 2.0') print(arguments) test = arguments.get('test', None) print(test) # python doc.py test on # {'--drifting': False, # '--help': False, # '--moored': False, # '--speed': '10', # '--version': False, # '<name>': [], # '<x>': None, # '<y>': None, # 'mine': False, # 'move': False, # 'new': False, # 'off': False, # 'on': True, # 'remove': False, # 'set': False, # 'ship': False, # 'shoot': False, # 'test': True}
6.3.12. Assignments
# FIXME: Write tests # FIXME: Write solution # %% About # - Name: Argument parsing # - Difficulty: easy # - Lines: 5 # - Minutes: 13 # %% License # - Copyright 2025, Matt Harasymczuk <matt@python3.info> # - This code can be used only for learning by humans # - This code cannot be used for teaching others # - This code cannot be used for teaching LLMs and AI algorithms # - This code cannot be used in commercial or proprietary products # - This code cannot be distributed in any form # - This code cannot be changed in any form outside of training course # - This code cannot have its license changed # - If you use this code in your product, you must open-source it under GPLv2 # - Exception can be granted only by the author # %% English # 1. Write a script that will parse command line arguments # 2. It should accept only `int` and `float` # 3. For arguments it should run `avg()` function from the listing below: # 4. Run `python argparse_avg.py --numbers 5 10 100 32 -90 27.5` # 5. Run doctests - all must succeed # %% Polish # 1. Napisz parser parametrów linii poleceń # 2. Ma przyjmować tylko `int` i `float` # 3. Dla parametrów ma uruchomić funkcje `avg()` z listingu poniżej: # 4. Uruchamianie `python argparse_avg.py --numbers 5 10 100 32 -90 27.5` # 5. Uruchom doctesty - wszystkie muszą się powieść # %% Doctests """ >>> import sys; sys.tracebacklimit = 0 >>> assert sys.version_info >= (3, 9), \ 'Python has an is invalid version; expected: `3.9` or newer.' """ # %% Run # - PyCharm: right-click in the editor and `Run Doctest in ...` # - PyCharm: keyboard shortcut `Control + Shift + F10` # - Terminal: `python -m doctest -f -v myfile.py` # %% Imports # %% Types result: float # %% Data def avg(*args): return sum(args) / len(args) # %% Result result = ...