jsonargparse icon indicating copy to clipboard operation
jsonargparse copied to clipboard

Generating yaml config with sub_commands

Open JonnyDorsey opened this issue 3 years ago • 3 comments

📚 Documentation improvement

Maybe I am just missing something from the documentation, but I would like to generate a config file from a parser with several sub_commands.

I have the argparser setup and working with sub_commands, (via jsonarparse just fine) but I haven't found out a way generate a config file for the entire parser.

# One of several sub parsers
create_parser = ArgumentParser()
create_parser.add_argument( "--name")
create_parser.add_argument( "--path")
create_parser.add_argument( "--ext")
create_parser.add_argument('--config', action=ActionConfigFile)
# Main Parser
parser = ArgumentParser(description="Emulator Runner CLI")
parser.add_argument("--level0_arg")
parser.add_argument('--config', action=ActionConfigFile)
sub_create = parser.add_subcommands(title="actions", required=False, dest="actions")
sub_create.add_subcommand('create', create_parser)

parser.parse_args()

Applying the --print_config > config.yaml option, with either generate only the main parser option, or if the create sub-command is passed will generate the sub_command config options, but not a config with both.

I have attempted to use the ArgumentParser.save() method instead but that still requires the passing in of the create namespace, and hence only generates a config for that section of the parser.

Is this behavior supported? If so is it documented? If its not document could it be added?

Thanks! Loving this package so far.

JonnyDorsey avatar Aug 30 '22 00:08 JonnyDorsey

Print global config without subcommand:

$ ./issue_156.py --print_config
level0_arg: null

Print config for a single subcommand:

$ ./issue_156.py create --print_config
name: null
path: null
ext: null

Print global config with a subcommand:

$ ./issue_156.py --print_config create
level0_arg: null
create:
  name: null
  path: null
  ext: null

It would be great if you create a pull request showing how you would improve the documentation so that this is explained better.

mauvilsa avatar Aug 30 '22 06:08 mauvilsa

Thanks for responding so promptly @mauvilsa, that definitely makes sense. I will try and find time tomorrow to PR an additional statement in the docs which specifies how --print-configs can be used with subcommands.

I think the only question that I have remaining, is why print_config with a list/set of subcommands are not valid. A quick test with my toy problem tells me that it is not currently supported as it prompts the user to select a single valid subcommand. I'm obviously a very new user to this package; however, I would have expected ...

$ ./issue_156.py --print_config create

to also be able to handle

$ ./issue_156.py --print_config [ create, delete, copy, move] 

or even to recurse into every subcommand, since the user is allowed to create an arbitrary number/structure of subcommands.

Cheers!

JonnyDorsey avatar Aug 30 '22 07:08 JonnyDorsey

I think the only question that I have remaining, is why print_config with a list/set of subcommands are not valid. A quick test with my toy problem tells me that it is not currently supported as it prompts the user to select a single valid subcommand.

Indeed this is not supported. --print_config is an argument like any other and the parsing is designed to consider only a single subcommand. This is the standard way that CLIs with subcommands work. Take for example git. It is only possible to run one subcommand at a time, e.g. git status or git commit, not git status commit expecting that status is run first and then commit. I don't know any CLI which is able to run multiple subcommands in a single call. It is better to stay with more standard behaviors to make it easier for users of the CLIs to learn how to use them.

Furthermore, with jsonargparse it is possible to have nested subcommands, which works like:

$ ./cli.py [global options] sublevel1 [level1 options] sublevel2 [level2 options] ...

If it were possible to have multiple level 1 subcommands, then it isn't possible to distinguish if the user is intending to run a level 1 subcommand or a nested level 2 subcommand.

You want --print_config to work for multiple subcommands even though later only one subcommand can be run at a time? Or you want to run multiple subcommands in a single call? Depending on what you want to do, subcommands might not be the way to achieve it. Perhaps you can explain a bit more what is your objective.

mauvilsa avatar Aug 30 '22 21:08 mauvilsa

You want --print_config to work for multiple subcommands even though later only one subcommand can be run at a time? Or you want to run multiple subcommands in a single call?

@JonnyDorsey can you please answer my questions.

mauvilsa avatar Nov 09 '22 06:11 mauvilsa