Home > Back-end >  Extract script parameter name and value from string [duplicate]
Extract script parameter name and value from string [duplicate]

Time:09-27

I currently have a process executor which executes a script along with parameters. The script and parameters are user provided.

  execute_script(script_name: str, parameters: str) -> None :
        // Some logic
        subprocess.Popen( ....)

The user provides both script name and parameters as a string. The execute_script(...) is a backend function which gets eventually invoked by an API exposed to the user. So, even though the parameters are executed as command-line arguments, they are not received as command-line arguments, but rather string variables.

For example:

  • script_name="sendEmail", parameters="--subject 'URGENT' --to '[email protected], [email protected]'"
  • script_name="calculatePerformance", parameters="--revenue 193456343 --tax_per 32543 --operating_cost 3452564.256 --includeVacationDays"
  • script_name="generate_report", parameters"--duration 'quarterly' --dept 'Finance'"

I do not have control over the parameters being sent by yer user. We have a lot of such script and they keep increasing. So keeping a track of potential parameters per script is not feasible.

I need to ensure that only a permitted values are used for certain parameters when used in conjunction with particular scripts. For Example:

  • the duration can ONLY be quarterly or monthly if script is generate_report. For any other script, any value can be provided.

I want to convert the parameters provided to the function from a string to a map, so that it is much more easier to extract and validate values for a script parameter.

Using space as delimiter to split and parse the string does not seem to be cleanest approach. Is there a more compact way to convert the parameters from string to map ? Alternatively, any other suggestions for parsing the string?

CodePudding user response:

I think you could get away with using a combination of shlex and argparse.

Use shlex.split as a way to tokenize the arguments, and then use argparse.ArgumentParser with parse_known_args to figure out the values you care about inspecting.

import argparse
import shlex

script_name = "generate_report"
parameters = "--duration 'quarterly' --dept 'Finance'"
parser_argv = [script_name, *shlex.split(parameters)]

parser = argparse.ArgumentParser()
parser.add_argument("--duration")
args, unknown = parser.parse_known_args(parser_argv)

if script_name == "generate_report":
    if args.duration not in {"quarterly", "monthly"}:
        raise ValueError(
            f"Incorrect duration for generate_report: {args.duration}"
        )

A nice thing about this design, is that if the scripts you end up invoking are already in python, you could expose the argparse setup in these tools and use them directly your method.

This would mean that you don't duplicate the parser code, allowing you to do validation as close as possible to the actual scripts inside this validator.

  • Related