You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
7.1 KiB

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