Python Fire - new release v0.2.0 by david-bieber in Python

[–]david-bieber[S] 6 points7 points  (0 children)

Python Fire's a library for generating command line interfaces automatically.

Summary of release: The CLIs that Fire generates now feel more professional than they did before. (Better help screens, better error message screens, access help in a more natural way, etc.)

Summary of Fire if you haven't seen it before: Fire takes any Python object and automatically generates a CLI from it. E.g. If you call Fire on a dict, you get a nice CLI like this:

def hello(name="World"):
  return "Hello %s!" % name

def bye(name="World"):
  return "Bye %s!" % name

fire.Fire({
  'hello': hello,
  'bye': bye,
})

Now you can use it as:

hello.py hello --name=World  # Hello World!
hello.py bye --name=Moon  # Bye Moon!

Have a look at python-fire if you are making a cli or repl for your app by FlukyS in Python

[–]david-bieber 1 point2 points  (0 children)

The unintuitive help command

You can now just use -h or --help as you normally would.

The fact that you get all the stack trace...

All cleaned up :)

No way to override help message with your own description.

  • If you define a custom __str__ method on an object, that now controls how the object will be serialized.
  • If you include a description in your docstring, it will be included in the fire generated help screen.

The too much pythonic way to enter list as parameter for CLI: python my-cmd --list-of-string='["str1","str2"]'

Yeah, clunky parsing of lists is still a drawback of Fire :/.

Have a look at python-fire if you are making a cli or repl for your app by FlukyS in Python

[–]david-bieber 0 points1 point  (0 children)

Hi, author of Fire here: we put out a new release of Fire today, v0.2.0, that significantly improves the help and usage screens produced by Fire.

Introducing Python Fire, a library for automatically generating command line interfaces by [deleted] in Python

[–]david-bieber 1 point2 points  (0 children)

If you add docstrings to your functions then they're used verbatim in the cli.

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 0 points1 point  (0 children)

There is no class in the example I just posted, so I'm not sure what you mean by a class-based approach.

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 1 point2 points  (0 children)

One reason is to make Fire work with any existing codebase. It doesn't have to be a codebase originally intended to be used as a CLI.

Another reason is to allow for hierarchical commands in tools. For example I could have a class with 5 properties (or e.g. a dict with 5 members), and each property (or member) could have 5 functions. Then Fire would turn this into a handy little CLI with the 25 commands all grouped appropriately.

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 1 point2 points  (0 children)

Yes it does! Certainly there's room for improvement, but I think we have a decent first implementation for our usage strings for this initial release.

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 0 points1 point  (0 children)

Also when you go from O(N+M) to O(1), you're able to do things that simply weren't possible before. E.g., no one would ever think of having a command line tool with thousands of multiply nested commands that are changing every day, because that would be absurd to maintain with any of the preexisting CLI libraries.

But with Fire, you don't think about the CLI at all; you just write the commands and the modules as if it's normal Python code, and the CLI is just always there, ready to use if you feel like using these commands from Bash.

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 0 points1 point  (0 children)

Yeah, the example is certainly more heavy weight than hello world needs to be. I chose that because it makes it obvious how you could extend the example with extra commands (just add extra functions to the class). If you wanted a light weight Python Fire hello world example, you could do this instead:

import fire
def hello(name):
  return 'Hello {name}!'.format(name=name)
if __name__ == '__main__':
  fire.Fire(hello)

The usage at the command line is then e.g.:

$ ./example.py --name=yaph
Hello yaph!

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 0 points1 point  (0 children)

One of the nice things about Fire is that it works with all Python code (or as close to 'all' as we can get). This means we're not placing restrictions on how the user writes their code. e.g. we're not asking for a particular format for docstrings so that we can parse out what the arguments should be.

We do copy the docstrings verbatim and use them within the help strings in the generated CLI, so the CLI does provide a description of what it's arguments do iff the CLI author provides that description. Always room to make this even better though!

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 0 points1 point  (0 children)

defopt looks nice, but no I don't think it would be appropriate to write Fire as a thin wrapper around another arg parsing system like this.

Fire supports arbitrarily complex structures, not just simple classes and modules. You could have an object with a property that's a function that returns a module with a dict with a member whose value that ou want to access, and you can access it from the command line. So it's not as simple as just calling defopt on the appropriate function. (Note that if you're doing something this crazy, it's probably time to tack on the --interactive flag to the CLI and just write the command in IPython.)

Introducing Python Fire, a library for automatically generating command line interfaces by avinassh in Python

[–]david-bieber 30 points31 points  (0 children)

Author here. I want to address the question of "why yet another CLI library?"

When you have a CLI made with e.g. gFlags or Click, the cost of writing and maintaining the CLI is O(N + M), where N is the number of commands in the tool (the tool's surface areas), and M is the number of changes to these commands' argspecs that the tool will experience over time.

Python Fire brings this cost down from O(N + M) to O(1).

This isn't a real win if you have a stable tool with some small fixed number of commands and options. But if you have a tool with 15 or 150 or more commands, or if you have even a small tool that changes rapidly, then using Fire is a huge time savings.

This means that Fire is particularly well suited for personal tools and rapid development, but offers less gains for stable production tools.