1Argh: The Natural CLI 2===================== 3 4.. image:: https://img.shields.io/coveralls/neithere/argh.svg 5 :target: https://coveralls.io/r/neithere/argh 6 7.. image:: https://img.shields.io/travis/neithere/argh.svg 8 :target: https://travis-ci.org/neithere/argh 9 10.. image:: https://img.shields.io/pypi/format/argh.svg 11 :target: https://pypi.python.org/pypi/argh 12 13.. image:: https://img.shields.io/pypi/status/argh.svg 14 :target: https://pypi.python.org/pypi/argh 15 16.. image:: https://img.shields.io/pypi/v/argh.svg 17 :target: https://pypi.python.org/pypi/argh 18 19.. image:: https://img.shields.io/pypi/pyversions/argh.svg 20 :target: https://pypi.python.org/pypi/argh 21 22.. image:: https://img.shields.io/pypi/dd/argh.svg 23 :target: https://pypi.python.org/pypi/argh 24 25.. image:: https://readthedocs.org/projects/argh/badge/?version=stable 26 :target: http://argh.readthedocs.org/en/stable/ 27 28.. image:: https://readthedocs.org/projects/argh/badge/?version=latest 29 :target: http://argh.readthedocs.org/en/latest/ 30 31Building a command-line interface? Found yourself uttering "argh!" while 32struggling with the API of `argparse`? Don't like the complexity but need 33the power? 34 35.. epigraph:: 36 37 Everything should be made as simple as possible, but no simpler. 38 39 -- Albert Einstein (probably) 40 41`Argh` is a smart wrapper for `argparse`. `Argparse` is a very powerful tool; 42`Argh` just makes it easy to use. 43 44In a nutshell 45------------- 46 47`Argh`-powered applications are *simple* but *flexible*: 48 49:Modular: 50 Declaration of commands can be decoupled from assembling and dispatching; 51 52:Pythonic: 53 Commands are declared naturally, no complex API calls in most cases; 54 55:Reusable: 56 Commands are plain functions, can be used directly outside of CLI context; 57 58:Layered: 59 The complexity of code raises with requirements; 60 61:Transparent: 62 The full power of argparse is available whenever needed; 63 64:Namespaced: 65 Nested commands are a piece of cake, no messing with subparsers (though 66 they are of course used under the hood); 67 68:Term-Friendly: 69 Command output is processed with respect to stream encoding; 70 71:Unobtrusive: 72 `Argh` can dispatch a subset of pure-`argparse` code, and pure-`argparse` 73 code can update and dispatch a parser assembled with `Argh`; 74 75:DRY: 76 The amount of boilerplate code is minimal; among other things, `Argh` will: 77 78 * infer command name from function name; 79 * infer arguments from function signature; 80 * infer argument type from the default value; 81 * infer argument action from the default value (for booleans); 82 * add an alias root command ``help`` for the ``--help`` argument. 83 84:NIH free: 85 `Argh` supports *completion*, *progress bars* and everything else by being 86 friendly to excellent 3rd-party libraries. No need to reinvent the wheel. 87 88Sounds good? Check the tutorial! 89 90Relation to argparse 91-------------------- 92 93`Argh` is fully compatible with `argparse`. You can mix `Argh`-agnostic and 94`Argh`-aware code. Just keep in mind that the dispatcher does some extra work 95that a custom dispatcher may not do. 96 97Installation 98------------ 99 100Using pip:: 101 102 $ pip install argh 103 104Arch Linux (AUR):: 105 106 $ yaourt python-argh 107 108Examples 109-------- 110 111A very simple application with one command: 112 113.. code-block:: python 114 115 import argh 116 117 def main(): 118 return 'Hello world' 119 120 argh.dispatch_command(main) 121 122Run it: 123 124.. code-block:: bash 125 126 $ ./app.py 127 Hello world 128 129A potentially modular application with multiple commands: 130 131.. code-block:: python 132 133 import argh 134 135 # declaring: 136 137 def echo(text): 138 "Returns given word as is." 139 return text 140 141 def greet(name, greeting='Hello'): 142 "Greets the user with given name. The greeting is customizable." 143 return greeting + ', ' + name 144 145 # assembling: 146 147 parser = argh.ArghParser() 148 parser.add_commands([echo, greet]) 149 150 # dispatching: 151 152 if __name__ == '__main__': 153 parser.dispatch() 154 155Of course it works: 156 157.. code-block:: bash 158 159 $ ./app.py greet Andy 160 Hello, Andy 161 162 $ ./app.py greet Andy -g Arrrgh 163 Arrrgh, Andy 164 165Here's the auto-generated help for this application (note how the docstrings 166are reused):: 167 168 $ ./app.py help 169 170 usage: app.py {echo,greet} ... 171 172 positional arguments: 173 echo Returns given word as is. 174 greet Greets the user with given name. The greeting is customizable. 175 176...and for a specific command (an ordinary function signature is converted 177to CLI arguments):: 178 179 $ ./app.py help greet 180 181 usage: app.py greet [-g GREETING] name 182 183 Greets the user with given name. The greeting is customizable. 184 185 positional arguments: 186 name 187 188 optional arguments: 189 -g GREETING, --greeting GREETING 'Hello' 190 191(The help messages have been simplified a bit for brevity.) 192 193`Argh` easily maps plain Python functions to CLI. Sometimes this is not 194enough; in these cases the powerful API of `argparse` is also available: 195 196.. code-block:: python 197 198 @arg('text', default='hello world', nargs='+', help='The message') 199 def echo(text): 200 print text 201 202The approaches can be safely combined even up to this level: 203 204.. code-block:: python 205 206 # adding help to `foo` which is in the function signature: 207 @arg('foo', help='blah') 208 # these are not in the signature so they go to **kwargs: 209 @arg('baz') 210 @arg('-q', '--quux') 211 # the function itself: 212 def cmd(foo, bar=1, *args, **kwargs): 213 yield foo 214 yield bar 215 yield ', '.join(args) 216 yield kwargs['baz'] 217 yield kwargs['quux'] 218 219Links 220----- 221 222* `Project home page`_ (GitHub) 223* `Documentation`_ (Read the Docs) 224* `Package distribution`_ (PyPI) 225* Questions, requests, bug reports, etc.: 226 227 * `Issue tracker`_ (GitHub) 228 * `Mailing list`_ (subscribe to get important announcements) 229 * Direct e-mail (neithere at gmail com) 230 231.. _project home page: http://github.com/neithere/argh/ 232.. _documentation: http://argh.readthedocs.org 233.. _package distribution: http://pypi.python.org/pypi/argh 234.. _issue tracker: http://github.com/neithere/argh/issues/ 235.. _mailing list: http://groups.google.com/group/argh-users 236 237Author 238------ 239 240Developed by Andrey Mikhaylenko since 2010. 241 242See file `AUTHORS` for a complete list of contributors to this library. 243 244Support 245------- 246 247The fastest way to improve this project is to submit tested and documented 248patches or detailed bug reports. 249 250Otherwise you can "flattr" me: |FlattrLink|_ 251 252.. _FlattrLink: https://flattr.com/submit/auto?user_id=neithere&url=http%3A%2F%2Fpypi.python.org%2Fpypi%2Fargh 253.. |FlattrLink| image:: https://api.flattr.com/button/flattr-badge-large.png 254 :alt: Flattr the Argh project 255 256Licensing 257--------- 258 259Argh is free software: you can redistribute it and/or modify 260it under the terms of the GNU Lesser General Public License as published 261by the Free Software Foundation, either version 3 of the License, or 262(at your option) any later version. 263 264Argh is distributed in the hope that it will be useful, 265but WITHOUT ANY WARRANTY; without even the implied warranty of 266MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 267GNU Lesser General Public License for more details. 268 269You should have received a copy of the GNU Lesser General Public License 270along with Argh. If not, see <http://gnu.org/licenses/>. 271