python-fire icon indicating copy to clipboard operation
python-fire copied to clipboard

display commands in a particular order

Open wiso opened this issue 4 years ago • 14 comments

In the help Fire displays commands in alphabetical order. It would be nice to be able to show them in a custom order specified by the user.

wiso avatar Nov 24 '20 10:11 wiso

@wiso can you please share some more information about how the current help result shows up and how would you like to customize it with an example or sample screenshots ?

vinayak-parab avatar Dec 17 '20 20:12 vinayak-parab

sure, actually is is very simple. This is the help I get

NAME
    run.py

SYNOPSIS
    run.py - COMMAND | VALUE

COMMANDS
    COMMAND is one of the following:

     background_prefit

     cfactor_sys

     check_workspace

     compare_fit_sys

     fit

     fit_nominal

     fit_sysgroup

     make_workspace

     make_xml

     matrix_sys

     plot_results

     plot_workspace

     signal_model_nominal
       run the signal shape model for the nominal case

     signal_model_systematic
       run the signal shape model for the systematic case, fixing most of the parameters to the nominal ones

VALUES
    VALUE is one of the following:

     basedir

     debug

     quantities

     regions

the commands are displayed in alphabetical order. I would like to customize that order.

wiso avatar Dec 18 '20 09:12 wiso

Hello @wiso I was able to reproduce the issue on my machine.

import fire

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

if name == 'main': fire.Fire(hello)

when I run the code with the following command : python firecli.py vinayak --help , it shows the list of commands that could be used in alphabetical order (screenshot attached). However, I do not see two different options where it displays the commands and values. How would you like the command display options to be customized ? Can you please elaborate on this part ? image

vinayak-parab avatar Dec 18 '20 14:12 vinayak-parab

There is no issue of any kind. My point is just that I would like to show then list of actions in an order defined by me, and not by alphabetical order.

wiso avatar Dec 18 '20 14:12 wiso

Ok got it. I understood your point.

vinayak-parab avatar Dec 18 '20 14:12 vinayak-parab

Option 1: When reordering sequence is specified using command line.

File-name = fire_test.py


import fire

class CustomSequence(object):
    def __init__(self, offset=1):
        self.offset = offset

    def generate(self, start, stop):
        return ' '.join(str(item) for item in range(start, stop, self.offset))

    def generate2(self):
        print("Function 1")

    def generated(self):
        print("Function 2")

    def cool(self):
        return "Function 3"
    def cool_for(self):
        print("Function 4")

    def rush_hour(self):
        print("Function 5")


if __name__ == '__main__':
    fire.Fire(CustomSequence())

Command line input with default sequence:

python fire_test.py --help

Output:

INFO: Showing help with the command 'fire_test.py -- --help'.

NAME
    fire_test.py

SYNOPSIS
    fire_test.py COMMAND | VALUE

COMMANDS
    COMMAND is one of the following:

     cool

     cool_for

     generate

     generate2

     generated

     rush_hour

VALUES
    VALUE is one of the following:

     offset

Command line input when a user specifies a sequence:

python fire_test.py --help rush_hour generate2

Output:

INFO: Showing help with the command 'fire_test.py -- --help'.

NAME
    fire_test.py

SYNOPSIS
    fire_test.py COMMAND | VALUE

COMMANDS
    COMMAND is one of the following:

     rush_hour

     generate2

     cool

     cool_for

     generate

     generated

VALUES
    VALUE is one of the following:

     offset

Option 2: When reordering sequence is specified in the file (fire_test.py in this case)

import fire

class CustomSequence(object):
    def __init__(self, offset=1):
        self.offset = offset

    def generate(self, start, stop):
        return ' '.join(str(item) for item in range(start, stop, self.offset))

    def generate2(self):
        print("Function 1")

    def generated(self):
        print("Function 2")

    def cool(self):
        return "Function 3"
    def cool_for(self):
        print("Function 4")

    def rush_hour(self):
        print("Function 5")

if __name__ == '__main__':
""" New paramter for the sequence has been added over here, which gets passed 
on through multiple calls to _MakeUsageDetailsSection function in helptext.py """
    fire.Fire(CustomSequence(), help_sequence = ["rush_hour","generate2"])

Output:

INFO: Showing help with the command 'fire_test.py -- --help'.

NAME
    fire_test.py

SYNOPSIS
    fire_test.py COMMAND | VALUE

COMMANDS
    COMMAND is one of the following:

     rush_hour

     generate2

     cool

     cool_for

     generate

     generated

VALUES
    VALUE is one of the following:

     offset

Please let me know either option 1 or 2 resolves the issue or is something else expected ?

varunjohn786 avatar Jan 07 '21 18:01 varunjohn786

Thank you. I haven't tested, but the last solution seems to do what I want in the simplest way.

wiso avatar Jan 08 '21 13:01 wiso

Please validate the changes and test it using the code in my forked repository branch. Since the code mentioned in above comments does not contain all the changes required in core.py and helptext.py files. Fire_test.py file for the testing will remain same from above comments or you can create your own script. You will just need to add a new parameter help_sequence while calling the Fire function

Link to the branch

varunjohn786 avatar Jan 08 '21 16:01 varunjohn786

your example works only if I run fire_test.py -- --help or fire_test.py --help or fire_test.py -h. If I run fire_test.py I get the alphabetical order.

wiso avatar Jan 09 '21 13:01 wiso

My initial understanding was that the reordering was required in only --help functionality of python-fire. But now, I have made changes to the code so that it now gives the reordered list of commands if you run python fire_test.py also.

Link to branch with code

varunjohn786 avatar Jan 09 '21 15:01 varunjohn786

ok, thanks.

There is a problem, I have added a documentation string in one function and the order is not correct

import fire

class CustomSequence(object):
    def __init__(self, offset=1):
        self.offset = offset

    def generate(self, start, stop):
        return ' '.join(str(item) for item in range(start, stop, self.offset))

    def generate2(self):
        print("Function 1")

    def generated(self):
        print("Function 2")

    def cool(self):
        return "Function 3"
    def cool_for(self):
        print("Function 4")

    def rush_hour(self):
        "zzzz"
        print("Function 5")

if __name__ == '__main__':
    """ New paramter for the sequence has been added over here, which gets passed 
on through multiple calls to _MakeUsageDetailsSection function in helptext.py """
    fire.Fire(CustomSequence(), help_sequence = ["rush_hour","generate2"])

wiso avatar Jan 09 '21 22:01 wiso

Thanks for pointing out the error. I have made changes to the code so that now documentation strings don't affect the reordering of the commands. I have also made changes so that every occurrence where commands get displayed as help will have this reordering.

Link to Branch

varunjohn786 avatar Jan 11 '21 17:01 varunjohn786

Thank, it works!

wiso avatar Jan 14 '21 18:01 wiso

Thanks for the confirmation. I will soon raise a pull request with the change.

varunjohn786 avatar Jan 15 '21 13:01 varunjohn786