API Reference
Argh
- class argh.ArghNamespace(*args, **kwargs)
A namespace object which collects the stack of functions.
- class argh.ArghParser(*args, **kwargs)
A subclass of
argparse.ArgumentParser
with support for and a couple of convenience methods.All methods are but wrappers for stand-alone functions
add_commands()
,autocomplete()
anddispatch()
.Uses
PARSER_FORMATTER
.- add_commands(*args, **kwargs) None
Wrapper for
add_commands()
.- Return type:
None
- autocomplete() None
Wrapper for
autocomplete()
.- Return type:
None
- dispatch(*args, **kwargs) str | None
Wrapper for
dispatch()
.- Return type:
str | None
- parse_args(args: Sequence[str] | None = None, namespace=None)
Wrapper for
argparse.ArgumentParser.parse_args()
. If namespace is not defined,argh.dispatching.ArghNamespace
is used. This is required for functions to be properly used as commands.
- set_default_command(*args, **kwargs) None
Wrapper for
set_default_command()
.- Return type:
None
- exception argh.AssemblingError
Raised if the parser could not be configured due to malformed or conflicting command declarations.
- exception argh.CommandError(*args, code=None)
Intended to be raised from within a command. The dispatcher wraps this exception by default and prints its message without traceback, then exits with exit code 1.
Useful for print-and-exit tasks when you expect a failure and don’t want to startle the ordinary user by the cryptic output.
Consider the following example:
def foo(args): try: ... except KeyError as e: print(u"Could not fetch item: {0}".format(e)) sys.exit(1)
It is exactly the same as:
def bar(args): try: ... except KeyError as e: raise CommandError(u"Could not fetch item: {0}".format(e))
To customize the exit status, pass an integer (as per
sys.exit()
) to thecode
keyword arg.This exception can be safely used in both print-style and yield-style commands (see Tutorial).
- exception argh.DispatchingError
Raised if the dispatching could not be completed due to misconfiguration which could not be determined on an earlier stage.
- class argh.EntryPoint(name: str | None = None, parser_kwargs: Dict[str, Any] | None = None)
An object to which functions can be attached and then dispatched.
When called with an argument, the argument (a function) is registered at this entry point as a command.
When called without an argument, dispatching is triggered with all previously registered commands.
Usage:
from argh import EntryPoint app = EntryPoint("main", {"description": "This is a cool app"}) @app def ls() -> Iterator[int]: for i in range(10): yield i @app def greet() -> str: return "hello" if __name__ == "__main__": app()
- argh.PARSER_FORMATTER
alias of
CustomFormatter
- argh.add_commands(parser: ArgumentParser, functions: List[Callable], name_mapping_policy: NameMappingPolicy | None = None, group_name: str | None = None, group_kwargs: Dict[str, Any] | None = None, func_kwargs: Dict[str, Any] | None = None) None
Adds given functions as commands to given parser.
- Parameters:
parser (ArgumentParser) – an
argparse.ArgumentParser
instance.functions (List[Callable]) – a list of functions. A subparser is created for each of them. If the function is decorated with
arg()
, the arguments are passed toargparse.ArgumentParser.add_argument()
. See alsodispatch()
for requirements concerning function signatures. The command name is inferred from the function name. Note that the underscores in the name are replaced with hyphens, i.e. function name “foo_bar” becomes command name “foo-bar”.name_mapping_policy (NameMappingPolicy | None) –
See
argh.assembling.NameMappingPolicy
.Added in version 0.30.
group_name (str | None) – an optional string representing the group of commands. For example, if a command named “hello” is added without the group name, it will be available as “prog.py hello”; if the group name if specified as “greet”, then the command will be accessible as “prog.py greet hello”. The group itself is not callable, so “prog.py greet” will fail and only display a help message.
func_kwargs (Dict[str, Any] | None) – a dict of keyword arguments to be passed to each nested ArgumentParser instance created per command (i.e. per function). Members of this dictionary have the highest priority, so a function’s docstring is overridden by a help in func_kwargs (if present).
group_kwargs (Dict[str, Any] | None) – a dict of keyword arguments to be passed to the nested ArgumentParser instance under given group_name.
- Return type:
None
Note
This function modifies the parser object. Generally side effects are bad practice but we don’t seem to have any choice as ArgumentParser is pretty opaque. You may prefer
add_commands()
for a bit more predictable API.Note
An attempt to add commands to a parser which already has a default function (e.g. added with
set_default_command()
) results in AssemblingError.
- argh.add_subcommands(parser: ArgumentParser, group_name: str, functions: List[Callable], **group_kwargs) None
A wrapper for
add_commands()
.These examples are equivalent:
add_commands( parser, [get, put], group_name="db", group_kwargs={ "title": "database commands", "help": "CRUD for our silly database" } ) add_subcommands( parser, "db", [get, put], title="database commands", help="CRUD for our database" )
- Parameters:
parser (ArgumentParser)
group_name (str)
- Return type:
None
- argh.aliases(*names: List[str]) Callable
Defines alternative command name(s) for given function (along with its original name). Usage:
@aliases("co", "check") def checkout(args): ...
The resulting command will be available as
checkout
,check
andco
.Added in version 0.19.
- argh.arg(*args: str, **kwargs) Callable
Declares an argument for given function. Does not register the function anywhere, nor does it modify the function in any way.
The signature of the decorator matches that of
argparse.ArgumentParser.add_argument()
, only some keywords are not required if they can be easily guessed (e.g. you don’t have to specify type or action when an int or bool default value is supplied).Note
completer is an exception; it’s not accepted by add_argument() but instead meant to be assigned to the action returned by that method, see https://kislyuk.github.io/argcomplete/#specifying-completers for details.
Typical use case: in combination with ordinary function signatures to add details that cannot be expressed with that syntax (e.g. help message).
Usage:
from argh import arg @arg("path", help="path to the file to load") @arg("--format", choices=["yaml","json"]) @arg("-v", "--verbosity", choices=range(0,3), default=2) def load( path: str, something: str | None = None, format: str = "json", dry_run: bool = False, verbosity: int = 1 ) -> None: loaders = {"json": json.load, "yaml": yaml.load} loader = loaders[args.format] data = loader(args.path) if not args.dry_run: if verbosity < 1: print("saving to the database") put_to_database(data)
In this example:
path declaration is extended with help;
format declaration is extended with choices;
dry_run declaration is not duplicated;
verbosity is extended with choices and the default value is overridden. (If both function signature and @arg define a default value for an argument, @arg wins.)
Note
It is recommended to avoid using this decorator unless there’s no way to tune the argument’s behaviour or presentation using ordinary function signatures. Readability counts, don’t repeat yourself.
The decorator is likely to be deprecated in the upcoming versions of Argh in favour of typing hints; see The Story of Argh.
- argh.confirm(action: str, default: bool | None = None, skip: bool = False) bool | None
A shortcut for typical confirmation prompt.
- Parameters:
action (str) – a string describing the action, e.g. “Apply changes”. A question mark will be appended.
default (bool | None) – bool or None. Determines what happens when user hits Enter without typing in a choice. If True, default choice is “yes”. If False, it is “no”. If None, the prompt keeps reappearing until user types in a choice (not necessarily acceptable) or until the number of iteration reaches the limit. Default is None.
skip (bool) – bool; if True, no interactive prompt is used and default choice is returned (useful for batch mode). Default is False.
- Return type:
bool | None
Usage:
def delete(key, *, silent=False): item = db.get(Item, args.key) if confirm(f"Delete {item.title}", default=True, skip=silent): item.delete() print("Item deleted.") else: print("Operation cancelled.")
Returns None on KeyboardInterrupt event.
- argh.dispatch(parser: ~argparse.ArgumentParser, argv: ~typing.List[str] | None = None, add_help_command: bool = False, completion: bool = True, output_file: ~typing.IO = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, errors_file: ~typing.IO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, raw_output: bool = False, namespace: ~argparse.Namespace | None = None, skip_unknown_args: bool = False, always_flush: bool = False) str | None
Parses given list of arguments using given parser, calls the relevant function and prints the result.
Internally calls
parse_and_resolve()
and thenrun_endpoint_function()
.- Parameters:
parser (ArgumentParser) – the ArgumentParser instance.
argv (List[str] | None) – a list of strings representing the arguments. If None,
sys.argv
is used instead. Default is None.add_help_command (bool) –
if True, converts first positional argument “help” to a keyword argument so that
help foo
becomesfoo --help
and displays usage information for “foo”. Default is False.Changed in version 0.30: The default value is now
False
instead ofTrue
.Deprecated since version 0.30: This argument will be removed in v.0.31. The user is expected to use
--help
instead ofhelp
.output_file (IO) – A file-like object for output. If None, the resulting lines are collected and returned as a string. Default is
sys.stdout
.errors_file (IO) – Same as output_file but for
sys.stderr
, and None is not accepted.raw_output (bool) – If True, results are written to the output file raw, without adding whitespaces or newlines between yielded strings. Default is False.
completion (bool) – If True, shell tab completion is enabled. Default is True. (You will also need to install it.) See
argh.completion
.skip_unknown_args (bool) – If True, unknown arguments do not cause an error (ArgumentParser.parse_known_args is used).
namespace (Namespace | None) –
Deprecated since version 0.31: This argument will be removed soon after v0.31.
always_flush (bool) –
If the output stream is not a terminal (i.e. redirected to a file or another process), it’s probably buffered. In most cases it doesn’t matter.
However, if the output of your program is generated with delays between the lines and you may want to redirect them to another process and immediately see the results (e.g. my_app.py | grep something), it’s a good idea to force flushing of the buffer.
Added in version 0.31.
- Return type:
str | None
By default the exceptions are not wrapped and will propagate. The only exception that is always wrapped is
CommandError
which is interpreted as an expected event so the traceback is hidden. You can also mark arbitrary exceptions as “wrappable” by using thewrap_errors()
decorator.Wrapped exceptions, or other “expected errors” like parse failures, will cause a SystemExit to be raised.
- argh.dispatch_command(function: Callable, *args, old_name_mapping_policy=True, **kwargs) None
A wrapper for
dispatch()
that creates a one-command parser. Usesargh.constants.PARSER_FORMATTER
.- Parameters:
old_name_mapping_policy –
Added in version 0.31.
If True, sets the default argument naming policy to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_HAS_DEFAULT, otherwise to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_KWONLY.
Warning
tho default will be changed to False in v.0.33 (or v.1.0).
function (Callable)
- Return type:
None
This:
dispatch_command(foo)
…is a shortcut for:
parser = ArgumentParser() set_default_command(parser, foo, name_mapping_policy=...) dispatch(parser)
This function can be also used as a decorator:
@dispatch_command def main(foo: int = 123) -> int: return foo + 1
- argh.dispatch_commands(functions: List[Callable], *args, old_name_mapping_policy=True, **kwargs) None
A wrapper for
dispatch()
that creates a parser, adds commands to the parser and dispatches them. UsesPARSER_FORMATTER
.- Parameters:
old_name_mapping_policy –
Added in version 0.31.
If True, sets the default argument naming policy to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_HAS_DEFAULT, otherwise to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_KWONLY.
Warning
tho default will be changed to False in v.0.33 (or v.1.0).
- Return type:
None
This:
dispatch_commands([foo, bar])
…is a shortcut for:
parser = ArgumentParser() add_commands(parser, [foo, bar], name_mapping_policy=...) dispatch(parser)
- argh.named(new_name: str) Callable
Sets given string as command name instead of the function name. The string is used verbatim without further processing.
Usage:
@named("load") def do_load_some_stuff_and_keep_the_original_function_name(args): ...
The resulting command will be available only as
load
. To add aliases without renaming the command, checkaliases()
.Added in version 0.19.
- argh.parse_and_resolve(parser: ArgumentParser, argv: List[str] | None = None, completion: bool = True, namespace: Namespace | None = None, skip_unknown_args: bool = False) Tuple[Callable | None, Namespace]
Added in version 0.30.
Parses CLI arguments and resolves the endpoint function.
- argh.run_endpoint_function(function: ~typing.Callable, namespace_obj: ~argparse.Namespace, output_file: ~typing.IO = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, errors_file: ~typing.IO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, raw_output: bool = False, always_flush: bool = False) str | None
Added in version 0.30.
Extracts arguments from the namespace object, calls the endpoint function and processes its output.
- argh.set_default_command(parser, function: Callable, name_mapping_policy: NameMappingPolicy | None = None) None
Sets default command (i.e. a function) for given parser.
If parser.description is empty and the function has a docstring, it is used as the description.
- Parameters:
function (Callable) – The function to use as the command.
name_mapping_policy (NameMappingPolicy | None)
- Name_mapping_policy:
The policy to use when mapping function arguments onto CLI arguments. See
NameMappingPolicy
. If not defined explicitly, BY_NAME_IF_KWONLY is used.Added in version 0.30.
Changed in version 0.30.2: Raises ArgumentNameMappingError if the policy was not explicitly defined and a non-kwonly argument has a default value. The reason is that it’s very likely to be a case of non-migrated code where the argument was intended to be mapped onto a CLI option. It’s better to fail explicitly than to silently change the CLI API.
- Return type:
None
Note
If there are both explicitly declared arguments (e.g. via
arg()
) and ones inferred from the function signature, declared ones will be merged into inferred ones. If an argument does not conform to the function signature, ArgumentNameMappingError is raised.Note
If the parser was created with
add_help=True
(which is by default), option name-h
is silently removed from any argument.
- argh.wrap_errors(errors: List[Type[Exception]] | None = None, processor: Callable | None = None, *args) Callable
Decorator. Wraps given exceptions into
CommandError
. Usage:@wrap_errors([AssertionError]) def foo(x=None, y=None): assert x or y, "x or y must be specified"
If the assertion fails, its message will be correctly printed and the stack hidden. This helps to avoid boilerplate code.
- Parameters:
errors (List[Type[Exception]] | None) – A list of exception classes to catch.
processor (Callable | None) –
A callable that expects the exception object and returns a string. For example, this renders all wrapped errors in red colour:
from termcolor import colored def failure(err): return colored(str(err), "red") @wrap_errors(processor=failure) def my_command(...): ...
- Return type:
Assembling
Functions and classes to properly assemble your commands in a parser.
- class argh.assembling.NameMappingPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Represents possible approaches to treat default values when inferring argument specification from function signature.
BY_NAME_IF_KWONLY is the default and recommended approach introduced in v0.30. It enables fine control over two aspects:
positional vs named;
required vs optional.
“Normal” arguments are identified by position, “kwonly” are identified by name, regardless of the presence of default values. A positional with a default value becomes optional but still positional (
nargs=OPTIONAL
). A kwonly argument without a default value becomes a required named argument.Example:
def func(alpha, beta=1, *, gamma, delta=2): ...
is equivalent to:
prog alpha [beta] --gamma [--delta DELTA]
That is,
alpha
and--gamma
are mandatory whilebeta
and--delta
are optional (they have default values).BY_NAME_IF_HAS_DEFAULT is very close to the the legacy approach (pre-v0.30). If a function argument has a default value, it becomes an “option” (called by name, like
--foo
); otherwise it’s treated as a positional argument.Example:
def func(alpha, beta=1, *, gamma, delta=2): ...
is equivalent to:
prog [--beta BETA] [--delta DELTA] alpha gamma
That is,
alpha
andgamma
are mandatory and positional, while--beta
and--delta
are optional (they have default values). Note that it’s impossible to have an optional positional or a mandatory named argument.The difference between this policy and the behaviour of Argh before v0.30 is in the treatment of kwonly arguments without default values: they used to become
--foo FOO
(required) but for the sake of simplicity they are treated as positionals. If you are already using kwonly args, please consider the better suited policy BY_NAME_IF_KWONLY instead.
It is recommended to migrate any older code to BY_NAME_IF_KWONLY.
Added in version 0.30.
- argh.assembling.add_commands(parser: ArgumentParser, functions: List[Callable], name_mapping_policy: NameMappingPolicy | None = None, group_name: str | None = None, group_kwargs: Dict[str, Any] | None = None, func_kwargs: Dict[str, Any] | None = None) None
Adds given functions as commands to given parser.
- Parameters:
parser (ArgumentParser) – an
argparse.ArgumentParser
instance.functions (List[Callable]) – a list of functions. A subparser is created for each of them. If the function is decorated with
arg()
, the arguments are passed toargparse.ArgumentParser.add_argument()
. See alsodispatch()
for requirements concerning function signatures. The command name is inferred from the function name. Note that the underscores in the name are replaced with hyphens, i.e. function name “foo_bar” becomes command name “foo-bar”.name_mapping_policy (NameMappingPolicy | None) –
See
argh.assembling.NameMappingPolicy
.Added in version 0.30.
group_name (str | None) – an optional string representing the group of commands. For example, if a command named “hello” is added without the group name, it will be available as “prog.py hello”; if the group name if specified as “greet”, then the command will be accessible as “prog.py greet hello”. The group itself is not callable, so “prog.py greet” will fail and only display a help message.
func_kwargs (Dict[str, Any] | None) – a dict of keyword arguments to be passed to each nested ArgumentParser instance created per command (i.e. per function). Members of this dictionary have the highest priority, so a function’s docstring is overridden by a help in func_kwargs (if present).
group_kwargs (Dict[str, Any] | None) – a dict of keyword arguments to be passed to the nested ArgumentParser instance under given group_name.
- Return type:
None
Note
This function modifies the parser object. Generally side effects are bad practice but we don’t seem to have any choice as ArgumentParser is pretty opaque. You may prefer
add_commands()
for a bit more predictable API.Note
An attempt to add commands to a parser which already has a default function (e.g. added with
set_default_command()
) results in AssemblingError.
- argh.assembling.add_subcommands(parser: ArgumentParser, group_name: str, functions: List[Callable], **group_kwargs) None
A wrapper for
add_commands()
.These examples are equivalent:
add_commands( parser, [get, put], group_name="db", group_kwargs={ "title": "database commands", "help": "CRUD for our silly database" } ) add_subcommands( parser, "db", [get, put], title="database commands", help="CRUD for our database" )
- Parameters:
parser (ArgumentParser)
group_name (str)
- Return type:
None
- argh.assembling.set_default_command(parser, function: Callable, name_mapping_policy: NameMappingPolicy | None = None) None
Sets default command (i.e. a function) for given parser.
If parser.description is empty and the function has a docstring, it is used as the description.
- Parameters:
function (Callable) – The function to use as the command.
name_mapping_policy (NameMappingPolicy | None)
- Name_mapping_policy:
The policy to use when mapping function arguments onto CLI arguments. See
NameMappingPolicy
. If not defined explicitly, BY_NAME_IF_KWONLY is used.Added in version 0.30.
Changed in version 0.30.2: Raises ArgumentNameMappingError if the policy was not explicitly defined and a non-kwonly argument has a default value. The reason is that it’s very likely to be a case of non-migrated code where the argument was intended to be mapped onto a CLI option. It’s better to fail explicitly than to silently change the CLI API.
- Return type:
None
Note
If there are both explicitly declared arguments (e.g. via
arg()
) and ones inferred from the function signature, declared ones will be merged into inferred ones. If an argument does not conform to the function signature, ArgumentNameMappingError is raised.Note
If the parser was created with
add_help=True
(which is by default), option name-h
is silently removed from any argument.
Dispatching
- class argh.dispatching.ArghNamespace(*args, **kwargs)
A namespace object which collects the stack of functions.
- class argh.dispatching.EntryPoint(name: str | None = None, parser_kwargs: Dict[str, Any] | None = None)
An object to which functions can be attached and then dispatched.
When called with an argument, the argument (a function) is registered at this entry point as a command.
When called without an argument, dispatching is triggered with all previously registered commands.
Usage:
from argh import EntryPoint app = EntryPoint("main", {"description": "This is a cool app"}) @app def ls() -> Iterator[int]: for i in range(10): yield i @app def greet() -> str: return "hello" if __name__ == "__main__": app()
- argh.dispatching.PARSER_FORMATTER
alias of
CustomFormatter
- argh.dispatching.dispatch(parser: ~argparse.ArgumentParser, argv: ~typing.List[str] | None = None, add_help_command: bool = False, completion: bool = True, output_file: ~typing.IO = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, errors_file: ~typing.IO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, raw_output: bool = False, namespace: ~argparse.Namespace | None = None, skip_unknown_args: bool = False, always_flush: bool = False) str | None
Parses given list of arguments using given parser, calls the relevant function and prints the result.
Internally calls
parse_and_resolve()
and thenrun_endpoint_function()
.- Parameters:
parser (ArgumentParser) – the ArgumentParser instance.
argv (List[str] | None) – a list of strings representing the arguments. If None,
sys.argv
is used instead. Default is None.add_help_command (bool) –
if True, converts first positional argument “help” to a keyword argument so that
help foo
becomesfoo --help
and displays usage information for “foo”. Default is False.Changed in version 0.30: The default value is now
False
instead ofTrue
.Deprecated since version 0.30: This argument will be removed in v.0.31. The user is expected to use
--help
instead ofhelp
.output_file (IO) – A file-like object for output. If None, the resulting lines are collected and returned as a string. Default is
sys.stdout
.errors_file (IO) – Same as output_file but for
sys.stderr
, and None is not accepted.raw_output (bool) – If True, results are written to the output file raw, without adding whitespaces or newlines between yielded strings. Default is False.
completion (bool) – If True, shell tab completion is enabled. Default is True. (You will also need to install it.) See
argh.completion
.skip_unknown_args (bool) – If True, unknown arguments do not cause an error (ArgumentParser.parse_known_args is used).
namespace (Namespace | None) –
Deprecated since version 0.31: This argument will be removed soon after v0.31.
always_flush (bool) –
If the output stream is not a terminal (i.e. redirected to a file or another process), it’s probably buffered. In most cases it doesn’t matter.
However, if the output of your program is generated with delays between the lines and you may want to redirect them to another process and immediately see the results (e.g. my_app.py | grep something), it’s a good idea to force flushing of the buffer.
Added in version 0.31.
- Return type:
str | None
By default the exceptions are not wrapped and will propagate. The only exception that is always wrapped is
CommandError
which is interpreted as an expected event so the traceback is hidden. You can also mark arbitrary exceptions as “wrappable” by using thewrap_errors()
decorator.Wrapped exceptions, or other “expected errors” like parse failures, will cause a SystemExit to be raised.
- argh.dispatching.dispatch_command(function: Callable, *args, old_name_mapping_policy=True, **kwargs) None
A wrapper for
dispatch()
that creates a one-command parser. Usesargh.constants.PARSER_FORMATTER
.- Parameters:
old_name_mapping_policy –
Added in version 0.31.
If True, sets the default argument naming policy to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_HAS_DEFAULT, otherwise to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_KWONLY.
Warning
tho default will be changed to False in v.0.33 (or v.1.0).
function (Callable)
- Return type:
None
This:
dispatch_command(foo)
…is a shortcut for:
parser = ArgumentParser() set_default_command(parser, foo, name_mapping_policy=...) dispatch(parser)
This function can be also used as a decorator:
@dispatch_command def main(foo: int = 123) -> int: return foo + 1
- argh.dispatching.dispatch_commands(functions: List[Callable], *args, old_name_mapping_policy=True, **kwargs) None
A wrapper for
dispatch()
that creates a parser, adds commands to the parser and dispatches them. UsesPARSER_FORMATTER
.- Parameters:
old_name_mapping_policy –
Added in version 0.31.
If True, sets the default argument naming policy to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_HAS_DEFAULT, otherwise to ~argh.assembling.NameMappingPolicy.BY_NAME_IF_KWONLY.
Warning
tho default will be changed to False in v.0.33 (or v.1.0).
- Return type:
None
This:
dispatch_commands([foo, bar])
…is a shortcut for:
parser = ArgumentParser() add_commands(parser, [foo, bar], name_mapping_policy=...) dispatch(parser)
- argh.dispatching.parse_and_resolve(parser: ArgumentParser, argv: List[str] | None = None, completion: bool = True, namespace: Namespace | None = None, skip_unknown_args: bool = False) Tuple[Callable | None, Namespace]
Added in version 0.30.
Parses CLI arguments and resolves the endpoint function.
- argh.dispatching.run_endpoint_function(function: ~typing.Callable, namespace_obj: ~argparse.Namespace, output_file: ~typing.IO = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, errors_file: ~typing.IO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, raw_output: bool = False, always_flush: bool = False) str | None
Added in version 0.30.
Extracts arguments from the namespace object, calls the endpoint function and processes its output.
Command decorators
- argh.decorators.aliases(*names: List[str]) Callable
Defines alternative command name(s) for given function (along with its original name). Usage:
@aliases("co", "check") def checkout(args): ...
The resulting command will be available as
checkout
,check
andco
.Added in version 0.19.
- argh.decorators.arg(*args: str, **kwargs) Callable
Declares an argument for given function. Does not register the function anywhere, nor does it modify the function in any way.
The signature of the decorator matches that of
argparse.ArgumentParser.add_argument()
, only some keywords are not required if they can be easily guessed (e.g. you don’t have to specify type or action when an int or bool default value is supplied).Note
completer is an exception; it’s not accepted by add_argument() but instead meant to be assigned to the action returned by that method, see https://kislyuk.github.io/argcomplete/#specifying-completers for details.
Typical use case: in combination with ordinary function signatures to add details that cannot be expressed with that syntax (e.g. help message).
Usage:
from argh import arg @arg("path", help="path to the file to load") @arg("--format", choices=["yaml","json"]) @arg("-v", "--verbosity", choices=range(0,3), default=2) def load( path: str, something: str | None = None, format: str = "json", dry_run: bool = False, verbosity: int = 1 ) -> None: loaders = {"json": json.load, "yaml": yaml.load} loader = loaders[args.format] data = loader(args.path) if not args.dry_run: if verbosity < 1: print("saving to the database") put_to_database(data)
In this example:
path declaration is extended with help;
format declaration is extended with choices;
dry_run declaration is not duplicated;
verbosity is extended with choices and the default value is overridden. (If both function signature and @arg define a default value for an argument, @arg wins.)
Note
It is recommended to avoid using this decorator unless there’s no way to tune the argument’s behaviour or presentation using ordinary function signatures. Readability counts, don’t repeat yourself.
The decorator is likely to be deprecated in the upcoming versions of Argh in favour of typing hints; see The Story of Argh.
- argh.decorators.named(new_name: str) Callable
Sets given string as command name instead of the function name. The string is used verbatim without further processing.
Usage:
@named("load") def do_load_some_stuff_and_keep_the_original_function_name(args): ...
The resulting command will be available only as
load
. To add aliases without renaming the command, checkaliases()
.Added in version 0.19.
- argh.decorators.wrap_errors(errors: List[Type[Exception]] | None = None, processor: Callable | None = None, *args) Callable
Decorator. Wraps given exceptions into
CommandError
. Usage:@wrap_errors([AssertionError]) def foo(x=None, y=None): assert x or y, "x or y must be specified"
If the assertion fails, its message will be correctly printed and the stack hidden. This helps to avoid boilerplate code.
- Parameters:
errors (List[Type[Exception]] | None) – A list of exception classes to catch.
processor (Callable | None) –
A callable that expects the exception object and returns a string. For example, this renders all wrapped errors in red colour:
from termcolor import colored def failure(err): return colored(str(err), "red") @wrap_errors(processor=failure) def my_command(...): ...
- Return type:
Interaction
- argh.interaction.confirm(action: str, default: bool | None = None, skip: bool = False) bool | None
A shortcut for typical confirmation prompt.
- Parameters:
action (str) – a string describing the action, e.g. “Apply changes”. A question mark will be appended.
default (bool | None) – bool or None. Determines what happens when user hits Enter without typing in a choice. If True, default choice is “yes”. If False, it is “no”. If None, the prompt keeps reappearing until user types in a choice (not necessarily acceptable) or until the number of iteration reaches the limit. Default is None.
skip (bool) – bool; if True, no interactive prompt is used and default choice is returned (useful for batch mode). Default is False.
- Return type:
bool | None
Usage:
def delete(key, *, silent=False): item = db.get(Item, args.key) if confirm(f"Delete {item.title}", default=True, skip=silent): item.delete() print("Item deleted.") else: print("Operation cancelled.")
Returns None on KeyboardInterrupt event.
Shell completion
Command and argument completion is a great way to reduce the number of keystrokes and improve user experience.
To display suggestions when you press tab, a shell must obtain choices from your program. It calls the program in a specific environment and expects it to return a list of relevant choices.
Argparse does not support completion out of the box. However, there are 3rd-party apps that do the job, such as argcomplete and python-selfcompletion.
Argh supports only argcomplete which doesn’t require subclassing the parser and monkey-patches it instead. Combining Argh with python-selfcompletion isn’t much harder though: simply use SelfCompletingArgumentParser instead of vanilla ArgumentParser.
See installation details and gotchas in the documentation of the 3rd-party app you’ve chosen for the completion backend.
Argh automatically enables completion if argcomplete is available
(see COMPLETION_ENABLED
). If completion is undesirable in given app by
design, it can be turned off by setting completion=False
in argh.dispatching.dispatch()
.
Note that you don’t have to add completion via Argh; it doesn’t matter whether you let it do it for you or use the underlying API.
Argument-level completion
Argcomplete supports custom “completers”. The documentation suggests adding the completer as an attribute of the argument parser action:
parser.add_argument("--env-var1").completer = EnvironCompleter
However, this doesn’t fit the normal Argh-assisted workflow.
It is recommended to use the arg()
decorator:
@arg("--env-var1", completer=EnvironCompleter)
def func(...):
...
- argh.completion.COMPLETION_ENABLED = False
Dynamically set to True on load if argcomplete was successfully imported.
- argh.completion.autocomplete(parser: ArgumentParser) None
Adds support for shell completion via argcomplete by patching given argparse.ArgumentParser (sub)class.
If completion is not enabled, logs a debug-level message.
- Parameters:
parser (ArgumentParser)
- Return type:
None
Helpers
- class argh.helpers.ArghParser(*args, **kwargs)
A subclass of
argparse.ArgumentParser
with support for and a couple of convenience methods.All methods are but wrappers for stand-alone functions
add_commands()
,autocomplete()
anddispatch()
.Uses
PARSER_FORMATTER
.- add_commands(*args, **kwargs) None
Wrapper for
add_commands()
.- Return type:
None
- autocomplete() None
Wrapper for
autocomplete()
.- Return type:
None
- dispatch(*args, **kwargs) str | None
Wrapper for
dispatch()
.- Return type:
str | None
- parse_args(args: Sequence[str] | None = None, namespace=None)
Wrapper for
argparse.ArgumentParser.parse_args()
. If namespace is not defined,argh.dispatching.ArghNamespace
is used. This is required for functions to be properly used as commands.
- set_default_command(*args, **kwargs) None
Wrapper for
set_default_command()
.- Return type:
None
Exceptions
- exception argh.exceptions.AssemblingError
Raised if the parser could not be configured due to malformed or conflicting command declarations.
- exception argh.exceptions.CommandError(*args, code=None)
Intended to be raised from within a command. The dispatcher wraps this exception by default and prints its message without traceback, then exits with exit code 1.
Useful for print-and-exit tasks when you expect a failure and don’t want to startle the ordinary user by the cryptic output.
Consider the following example:
def foo(args): try: ... except KeyError as e: print(u"Could not fetch item: {0}".format(e)) sys.exit(1)
It is exactly the same as:
def bar(args): try: ... except KeyError as e: raise CommandError(u"Could not fetch item: {0}".format(e))
To customize the exit status, pass an integer (as per
sys.exit()
) to thecode
keyword arg.This exception can be safely used in both print-style and yield-style commands (see Tutorial).
- exception argh.exceptions.DispatchingError
Raised if the dispatching could not be completed due to misconfiguration which could not be determined on an earlier stage.
Utilities
- exception argh.utils.ArghError
- exception argh.utils.CliArgToFuncArgGuessingError
- exception argh.utils.MixedPositionalAndOptionalArgsError
- exception argh.utils.SubparsersNotDefinedError
- exception argh.utils.TooManyPositionalArgumentNames
- argh.utils.get_subparsers(parser: ArgumentParser, create: bool = False) _SubParsersAction
Returns the argparse._SubParsersAction instance for given
argparse.ArgumentParser
instance as would have been returned byargparse.ArgumentParser.add_subparsers()
. The problem with the latter is that it only works once and raises an exception on the second attempt, and the public API seems to lack a method to get existing subparsers.- Parameters:
create (bool) – If True, creates the subparser if it does not exist. Default if False.
parser (ArgumentParser)
- Return type:
_SubParsersAction
- argh.utils.unindent(text: str) str
Given a multi-line string, decreases indentation of all lines so that the first non-empty line has zero indentation and the remaining lines are adjusted accordingly.
Constants
- argh.constants.ATTR_ALIASES = 'argh_aliases'
alternative command names
- argh.constants.ATTR_ARGS = 'argh_args'
declared arguments
- argh.constants.ATTR_NAME = 'argh_name'
explicit command name (differing from function name)
- argh.constants.ATTR_WRAPPED_EXCEPTIONS = 'argh_wrap_errors'
list of exception classes that should be wrapped and printed as results
- argh.constants.ATTR_WRAPPED_EXCEPTIONS_PROCESSOR = 'argh_wrap_errors_processor'
a function to preprocess the exception object when it is wrapped
- class argh.constants.CustomFormatter(prog, indent_increment=2, max_help_position=24, width=None)
A slightly customised
argparse.ArgumentDefaultsHelpFormatter
+argparse.RawDescriptionHelpFormatter
.
- argh.constants.DEFAULT_ARGUMENT_TEMPLATE = '%(default)s'
Default template of argument help message (see issue #64). The template
%(default)s
is used by argparse to display the argument’s default value.
- argh.constants.DEST_FUNCTION = 'function'
dest name for a function mapped to given endpoint (goes to Namespace obj)
- argh.constants.PARSER_FORMATTER
Default formatter (
CustomFormatter
) to be used in implicitly instantiated ArgumentParser.