Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse: Processing Certain Arguments Before Adding Others

Using python's argparse library, I would like to process the first few command-line arguments and use them to generate a list of choices for the other command-line arguments.

How can I process the first few arguments without argparse complaining about extra arguments that it doesn't expect (which I plan to add later)?

For example, I have a script that gets the username and password from the command-line, uses those to access available properties of an API, and then uses that list to restrict the values of a third argument:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('username', help='Your username.')
parser.add_argument('password', help='Your password.')
args = parser.parse_args() # Error here because a third argument exists on the command-line

response = requests.get(
    url='https://api.example.com/properties',
    auth=(args.username, args.password)
)

parser.add_argument(
    'property',
    choices=response.json()['properties'], # Validates the input
    help='The property you want to access.'
)
args = parser.parse_args()

I know I can just add all the arguments at once, and then validate the third argument myself manually, but I'm wondering if there's a way to natively do what I'm asking in the argparse library?

like image 902
ezgoodey Avatar asked Oct 24 '25 02:10

ezgoodey


1 Answers

parser = argparse.ArgumentParser()
parser.add_argument('username', help='Your username.')
parser.add_argument('password', help='Your password.')
parser.add_argument(
    'property',
    help='The property you want to access.'
)
args = parser.parse_args() 

response = requests.get(
    url='https://api.example.com/properties',
    auth=(args.username, args.password)
)
allowed_properties = response.json()['properties']
if args.property not in allowed_properties:
    parser.error('property not in allowed properties')

choices is not a complicated test. I'd recommend parsing all inputs, and then testing for this special case. Overall I think gives you better control, and better help and error display.

The parse_known_args approach is good to learn and occasionally use, but I don't think it's that great for this case. You don't get any extra points for embedding all argument testing in the parser.

like image 91
hpaulj Avatar answered Oct 25 '25 16:10

hpaulj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!