robotframework icon indicating copy to clipboard operation
robotframework copied to clipboard

public API to retrieve robot/rebot options (_cli_opts)

Open oboehmer opened this issue 2 years ago • 7 comments

I have now come by at least two use cases for a client python application to know about valid robot/rebot options.

I can retrieve the options via an internal call like

from robot.conf import RobotSettings
robot_options = [v[0] for v in RobotSettings()._cli_opts.values()]

but I would rather like this to be a public API.

oboehmer avatar May 02 '22 07:05 oboehmer

You can try the following in Python as well:

from robot.run import USAGE
print(USAGE)

and if you want the parser:

from robot.utils.argumentparser import ArgumentParser
argument_parser = ArgumentParser(USAGE)

elrandira avatar May 02 '22 09:05 elrandira

cheers.. the use case I came across is something like

from robot import run
from robot.conf import RobotSettings
robot_options = [v[0] for v in RobotSettings()._cli_opts.values()]

def call_robot(..., **kwargs):

    # do something with some of the arguments
    #..
    # call robot with valid opts, i.e. allow users to pass any valid
    # robot option
    robot_opts = {k: v for k, v in kwargs.items() if k in robot_options}
    run(..., **robot_opts)
    
call_robot(..., foo='bar', outputdir='/tmp')

so I just want to drop opts not valid (in real life I would print a warning or something like this).

oboehmer avatar May 02 '22 10:05 oboehmer

You can try the following in Python as well:

from robot.run import USAGE
print(USAGE)

this would require me parsing the text string for options, rather dirty..

oboehmer avatar May 02 '22 10:05 oboehmer

I haven't tested it but this would do it:

from robot.run import USAGE
from robot.utils.argumentparser import ArgumentParser
from robot.errors import DataError
import sys

argument_parser = ArgumentParser(USAGE)
try:
  opts, args = argument_parser.parse_args(sys.argv[1:])
except DataError as e:
  print("invalid params: {}".format(e))

Just digging into the code, I can see argumentparser implement getOpt which throws GetoptError when wrong parameters are provided:

    def _parse_args(self, args):
        args = [self._lowercase_long_option(a) for a in args]
        try:
            opts, args = getopt.getopt(args, self._short_opts, self._long_opts)
        except getopt.GetoptError as err:
            raise DataError(err.msg)
        return self._process_opts(opts), self._glob_args(args)

elrandira avatar May 02 '22 13:05 elrandira

This kind of an API would be convenient. Also Pabot has been few times broken due to it accessing this information using non-public APIs that have been changed slightly in different releases. Ping @mkorpela related to that.

Robot's whole command line option system isn't that convenient in general and be rewritten. We switch to using argparse and probably should add support for configuration files at the same time. That may be too big a task for RF 5.1, but could be possible in RF 6.0. We could, however, add an API to access options already in RF 5.1. Do you have concrete ideas how the API should look like?

pekkaklarck avatar May 05 '22 13:05 pekkaklarck

thanks for the comments, @pekkaklarck .. I think an api could return the valid options and default values, maybe something like

def robot_options():
    from robot.conf import RobotSettings
    return {e[0]: e[1] for e in RobotSettings()._cli_opts.values()}

def rebot_options():
    from robot.conf import RebotSettings
    return {e[0]: e[1] for e in RebotSettings()._cli_opts.values()}

oboehmer avatar May 06 '22 10:05 oboehmer

Would the above work with Pabot @mkorpela? Should we perhaps discuss this further on the #devel channel on Slack?

pekkaklarck avatar May 06 '22 16:05 pekkaklarck