-Defining and running commands is dead simple::
+Assume we need a CLI application which output is modulated by arguments::
+This is the whole application::
+ def main(name='unknown user'):
+ return 'Hello ' + name + '!'
That's it. And it works::
Nice for a quick'n'dirty script. A reusable app would look closer to this::
- if __name__ == '__main__':
-...and here's a bit more complex example (still pretty readable)::
def load(path, format='json'):
+ p.add_commands([load, dump])
+ if __name__ == '__main__':
And then call your script like this::
$ ./script.py load fixture.json
$ ./script.py load fixture.yaml --format=yaml
I guess you get the picture. Still, there's much more to commands than this.
-You'll want to provide help per command and per argument, you will want to
-specify aliases, data types, namespaces and... just read on.
+The examples above raise some questions, including:
+* why the ``@command`` decorator for just one of the two functions?
+* do ``return`` and ``print`` behave equally?
+* what's the difference between ``dispatch_command()`` from one example
+ and the more complex version from another one?
+Then, you'll want to provide help per command and per argument; to specify
+aliases, data types, namespaces and...
raise CommandError(error) # bail out, hide traceback
`Argh` will wrap this exception and choose the right way to display its
message (depending on how :func:`~argh.helpers.dispatch` was called).
+The decorator :func:`~argh.helpers.wrap_errors` reduces the code even further::
+ @wrap_errors(KeyError) # catch KeyError, show the message, hide traceback
+ return items[args.key] # raise KeyError
+Of course it should be used with care in more complex commands.