Hacker News new | ask | show | jobs
by tudborg 4432 days ago
It looks really well done.

I still prefer docopt (https://github.com/docopt/docopt) . It is so much simpler to use. Click seems to be a bit overengineered.

4 comments

As someone who has never used either, the documentation and simple example of Click won hands down.

I could use it for simple cases within 15 seconds of reading. Docopt not so much.

You're right - looking on the http://docopt.org/ page it's not immediately obvious how it works.

The general idea is that you don't specify any code, you just give the help message as text. Docopt parses that to figure out all the options etc and convert those into the parameters coming in to your system.

It's a really clever idea. You specify the human interface, docopt converts that into the code version (so long as you adhere to a few common conventions). I haven't seen a cleaner system anywhere.

From their example:

    """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 (-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)
That's brilliant. I wonder if there's a way to use docstrings like that to create REST services in Flask.
If you need to parse something as simple as `foo --option spam --option eggs` remembering both spam and eggs, docopt breaks down. You are also unable to compose an interface using docopt, if you want to allow plugins in a plugin system to add their own options for example.

docopt is much simpler because it's only capable of creating very trivial interfaces. That's perfectly fine if that's all what you want to do but it also makes docopt unusable, if that's not the case.

Maybe I'm misunderstanding but you could do:

    Usage:
      script.py --option=<name>...

    script.py --option spam --option eggs

    {
      "--option": [
        "spam", 
        "eggs"
      ]
    }
Example here [0].

I haven't pushed it too far so I'm sure there are other cases where you'd need to create a different command line api to have it work (that may or may not be an issue depending on your use case).

Regarding the other criticism, seems valid. In the docopt api can you have it do the parsing for you so you can edit the rules afterwards before you run them?

[0] http://try.docopt.org/?doc=Usage%3A%0D%0A++script.py+--optio...

I've used docopt for some tools, but argtools (and click it seems) is much more convenient, imo. It's very easy to remember the 1-2 decorators and probably most importantly, the command arguments and everything else are where the command is defined, not somewhere else.

When using docopt i spent much more time defining the docstring and figuring out the right way to write it, especially more complex scenarios.

I love docopt. My big draw is that I write the documentation only once - in the doc string where it should be. Click looks great, but there is no documentation in the code itself. You need to run the code to print the documentation.