typed-argument-parser icon indicating copy to clipboard operation
typed-argument-parser copied to clipboard

Load arguments from configuration file specified in argument

Open rubencart opened this issue 4 years ago • 5 comments

Is it possible to specify which configuration file to load in an argument? So instead of:

class Args(Tap):
    arg1: int
    arg2: str

args = Args(config_files=['my_config.txt']).parse_args()

Something like this:

class Args(Tap):
    arg1: int
    arg2: str
    cfg_file: ConfigFile

args = Args().parse_args()

For which you could then run something like python main.py --cfg_file cfg/train.yaml. If not, this would be a valuable improvement in my opinion. It makes sense that which config file will be loaded does not have to be hardcoded. The jsonargparse package offers a similar functionality: https://jsonargparse.readthedocs.io/en/stable/#configuration-files.

As a side question: can yaml or json files already be loaded?

rubencart avatar Feb 16 '21 09:02 rubencart

Hi @rubencart,

Yes, this is a great idea. @arbellea actually brought up this application in https://github.com/swansonk14/typed-argument-parser/issues/25#issuecomment-647029355, but we never ended up implementing it. It seems very reasonable to, during parse_args, check if an argument is of type TapConfig and then load that file in with _load_from_config_files. We'll add this in the near future.

Best, Kyle and Jesse

martinjm97 avatar Feb 20 '21 18:02 martinjm97

I see this related issue now :)

aarbelle avatar Apr 06 '21 06:04 aarbelle

Are there any plans of adding this feature? Yaml support would be great :)

michelkok avatar Nov 11 '21 09:11 michelkok

Yes, there are plans to add this feature at some point in the future. Any PRs are greatly appreciated. The changes necessary would be in: https://github.com/swansonk14/typed-argument-parser/blob/8cd23fb2ccfb4cd4ed599cb1451375059ca319f0/tap/tap.py#L643 and https://github.com/swansonk14/typed-argument-parser/blob/8cd23fb2ccfb4cd4ed599cb1451375059ca319f0/tap/tap.py#L624

The standard package seems to be pyyaml. The implementation would require a custom Loader and Dumper that work similarly to as_python_object and define_python_object_encoder.

martinjm97 avatar Nov 20 '21 22:11 martinjm97

I think there is two things, linking this to headers in the readme.

  1. Saving and loading arguments Here you could use a custom Loader and Dumper, although I do not see why you cannot use the default yaml.load and yaml.dump. I think they are more flexible than the JSONEncoder and handle all use-cases fine.

@martinjm97 I think you are mainly pointing me there, but I think that is not the request here.

  1. Loading from configuration files This is a slightly different use case, because here you'd want some config.yml as a configuration file (as in ConfigArgParse). It's different as the Dumper will encode the type in the string. But that is not something you'd usually write yourself in a config file. Tap should automatically parse it to the wanted type if possible. So an Iterable can become a set, tuple or list depending on the configuration. Edit: I see that something like this already happens parse_args.
print(yaml.dump({'name': 'TAP', 'traits': ['ONE_HAND', 'ONE_EYE'], 'sometuple': (2, 3), 'someset': {2, 3}}))

name: TAP
someset: !!set
  2: null
  3: null
sometuple: !!python/tuple
- 2
- 3
traits:
- ONE_HAND
- ONE_EYE

michelkok avatar Dec 07 '21 09:12 michelkok