How can I use click to parse a string for arguments?

2024/10/9 6:27:16

Say I have a list of strings containing arguments and options, with argparse, I’m able to parse this list using the parse_args function into an object, as follows:

import argparseextra_params = [‘—sum’, ‘7’, ‘-1’, ‘42’]parser=argparse.ArgumentParser(description=“argparse docs example”)
parser.add_argument(‘integers’, metavar=‘N’, type=int, nargs=‘+’,help=‘an integer for the accumulator’)
parser.add_argument(‘—sum’, dest=‘accumulate’, action=‘store_const’,const=sum, default=max,help=‘sum the integers (default: find the max)’)
parsed_object=parser.parse_args(extra_params)

Here, argparse has parsed a provided iterable of strings. Can one use click to also parse a provided iterable of strings?

I’ve searched through the API documentation for click and it appears that there’s a parse_args function within the *Command set of classes but don’t see anything in the docs around how I can do this. I’ve tried instantiating BaseCommand as well as Command but not sure how to get parse_args working without a correct context.

For broader context, this question is a result of having built a launcher application that end users use as a scaffold to launch their own applications. Here, the launcher consumes a number of arguments for which click decorators work perfectly. Unknown arguments can be handled as shown in the documentation here. This launcher then calls an end-user provided callable with these unparsed parameters. Click leaves unparsed parameters as a tuple of strings. How would the end-user, in this situation, be able to use Click to parse the argument's they're interested in? Here's a snippet to illustrate the issue:

import click
from typing import Tuple@click.command(name="TestLauncher", context_settings={"ignore_unknown_options": True
})
@click.option('--uri', '-u',help="URI for the server")
@click.argument('unprocessed_args', nargs=-1,type=click.UNPROCESSED)
def main(uri: str, unprocessed_args: Tuple[str, ...]) -> None:print(f"Was passed a URI of {uri}")print(f"Additional args are {unprocessed_args}")child_function(unprocessed_args)def child_function(unprocessed_args: Tuple[str, ...]) -> None:# How do I get Click to parse the provided args for me?passif __name__ == "__main__":# pylint: disable=no-value-for-parameter, unexpected-keyword-argmain()

Running this from the command line:

python3 so_test.py --uri test.com --prog-arg 10
Was passed a URI of test.com
Additional args are ('--prog-arg', '10')
Answer

For the calling function not knowing anything about parameters for the child function, you can try this:

@click.command(name="TestLauncher", context_settings={"ignore_unknown_options": True
})
@click.option('--uri', '-u',help="URI for the server")
@click.argument('unprocessed_args', nargs=-1,type=click.UNPROCESSED)
def main(uri: str, unprocessed_args: Tuple[str, ...]) -> None:print(f"Was passed a URI of {uri}")print(f"Additional args are {unprocessed_args}")unprocessed_args = dict([(unprocessed_args[i].replace('--', '').replace('-', '_'), unprocessed_args[i+1]) for i in range(0, len(unprocessed_args), 2)])click.get_current_context().invoke(child_function, **unprocessed_args)@click.command(context_settings={"ignore_unknown_options": True})
@click.option('-p', '--prog-arg')
def child_function(prog_arg: str, **kwargs) -> None:# How do I get Click to parse the provided args for me?print(f"Child function passed: {prog_arg}")# all remaining unknown options are in **kwargsif __name__ == "__main__":# pylint: disable=no-value-for-parameter, unexpected-keyword-argmain()

However, note that:

unprocessed_args = dict([(unprocessed_args[i].replace('--', '').replace('-', '_'), unprocessed_args[i+1]) for i in range(0, len(unprocessed_args), 2)])

This assumes you can only have one value per option. The alternative is to call your script by passing in options like below, splitting the string on = and doing whatever pre-formatting you deem necessary.

--prog-arg=<Your-desired-values>
https://en.xdnf.cn/q/70047.html

Related Q&A

Tornado and WTForms

I am using WTForms for the first time. Using WTForms to validate POST requests in Tornado Below is my forms forms.pyclass UserForm(Form):user = TextField(user, [validators.Length(min=23, max=23)])In t…

Modifying a python docstring with a decorator: Is it a good idea?

A python docstring must be given as a literal string; but sometimes its useful to have similar docstrings for several functions (e.g., different constructors), or several access methods might accept th…

Counting number of columns in text file with Python

I have two text files composed of spaced-separated columns. These are excerpts of these two files:FileA1 1742.420 -0.410 20.1530 0.4190 1.7080 0.59402 1872.060 0.070 21.4710 0.2950 0.0…

Django on Apache web server dict object has no attribute render_context

Im having a bit of a problem, I uploaded my Django project to a webserver running apache, mod_python, and django. On the computer I developed on the following works finenameBox = getNamesBox().render(l…

Verbose log abbriviations meaning in SVC, scikit-learn

I am looking for the meaning of verbose log abbriviations of SVC function in scikit-learn?If nSV is the number of support vectors, #iter is the number of iteration, what dose nBSV, rho,obj mean?This …

networkx draw_networkx_edges capstyle

Does anyone know if it is possible to have fine-grained control over line properties when drawing networkx edges via (for example) draw_networkx_edges? I would like to control the line solid_capstyle …

Setting up the path so AWS cli works properly

I installed AWSCLI by using:pip install --upgrade --user awscliNow if I type aws configure in the cmd I get: aws is not recognized as an internal or external command...Im pretty sure the path needs to …

Comparing value with neighbor elements in numpy

Lets say I have a numpy arraya b c A = i j ku v wI want to compare the value central element with some of its eight neighbor elements (along the axis or along the diagonal). Is there any faster way exc…

Is Python bad at XML? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, argum…

Conditional color with matplotlib scatter

I have the following Pandas Dataframe, where column a represents a dummy variable:What I would like to do is to give my markers a cmap=jet color following the value of column b, except when the value i…