Starting from any API component, we can get the underlying class and its parameters
>>> import datalad.api as dl
>>> dl.wtf
<function datalad.local.wtf.WTF.__call__(*, dataset=None, sensitive=None, sections=None, flavor='full', decor=None, clipboard=None)>
>>> from datalad.utils import get_wrapped_class
>>> cls=get_wrapped_class(dl.wtf)
>>> cls._params_
{'dataset': <datalad.support.param.Parameter at 0x7fdff72162f0>,
'sensitive': <datalad.support.param.Parameter at 0x7fdff72163e0>,
'sections': <datalad.support.param.Parameter at 0x7fdff72164a0>,
'flavor': <datalad.support.param.Parameter at 0x7fdff7216560>,
'decor': <datalad.support.param.Parameter at 0x7fdff7216620>,
'clipboard': <datalad.support.param.Parameter at 0x7fdff7216650>,
'return_type': <datalad.support.param.Parameter at 0x7fdff7fa3880>,
'result_filter': <datalad.support.param.Parameter at 0x7fdff7fa39a0>,
'result_xfm': <datalad.support.param.Parameter at 0x7fdff7fa3b20>,
'result_renderer': <datalad.support.param.Parameter at 0x7fdff7fa3b80>,
'on_failure': <datalad.support.param.Parameter at 0x7fdff7fa3c40>}
as seen above, this include all common command parameters too, so no special handling is needed for them.
ATM we cannot tell which parameters are deprecated and could be ignored datalad/datalad#6998
Each Parameter
instance can provide additional info. Parameter.constraints()
could be called to validate parameter values prior execution. type(Parameter.contraints)
could be used to select specialized input widgets (in some cases). Parameter .get_autodoc()
is not very useful, because it spells our constraints, and a GUI would reflect them in the interface directly.
>>> p = cls._params_['sections']
>>> p.constraints('some')
ValueError: value is not one of (None, 'configuration', ...
>>> type(p.constraints)
datalad.support.constraints.EnsureChoice
>>> p.get_autodoc('some')
"some : list of {None, 'configuration', 'credentials', 'datalad', 'dataset', 'dependencies', 'environment', 'extensions', 'git-annex', 'location', 'metadata_extractors', 'metadata_indexers', 'python', 'system', '*'}\n section to include. If not set - depends on flavor. '*' could be\n used to force all sections. [CMD: This option can be given multiple\n times. CMD]."
It is not possible to extract from a constraint whether one or more values can be passed to a parameter. For that, it seems the argparse
"action" configuration needs to be inspected and acted upon:
>>> p.cmd_kwargs
{'action': 'append', 'dest': 'sections', 'metavar': 'SECTION'}
likely other settings need to be taken into account too (nargs
, const
, choices
, required
). This is a complex problem. It seems to be best solved by a specialized solution like https://github.com/chriskiehl/Gooey but we are only using a subset of the capabilities of argparse
, so we might get away with something cheaper.
Parameter
exposes all argument diversity supported by argparse
though...
The parameter entry widget should likely maintain the signature order:
>>> from datalad.utils import get_sig_param_names
>>> get_sig_param_names(wtf, ('any',))
(['dataset', 'sensitive', 'sections', 'flavor', 'decor', 'clipboard'],)
Any common parameters (result rendering, etc) could be added via a standard widget set (unconditionally).