Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional command line arguments in Python using argparse

I'd like to have a program that takes a --action= flag, where the valid choices are dump and upload, with upload being the default. If (and only if) dump is selected, I'd like there to also be a --dump-format= option. Is there a way to express this using argparse, or do I need to just accept all the arguments and do the logic myself.

like image 243
Alex Gaynor Avatar asked Feb 29 '12 20:02

Alex Gaynor


People also ask

How do you add arguments in Argparse?

After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments. To add your arguments, use parser. add_argument() .

How do you create an argument parser in Python?

# construct the argument parser and parse the arguments ap = argparse. ArgumentParser() ap. add_argument("-d", "--dataset", required=True, help="Path to the directory of indexed images") ap. add_argument("-f", "--features-db", required=True, help="Path to the features database") ap.


1 Answers

The argparse module offers a way to do this without implementing your own requiredness checks. The example below uses "subparsers" or "sub commands". I've implemented a subparser for "dump" and one for "format".

import argparse  parser = argparse.ArgumentParser() parser.add_argument('file', help='The file you want to act on.') subparsers = parser.add_subparsers(dest='subcommand') subparsers.required = True  # required since 3.7  #  subparser for dump parser_dump = subparsers.add_parser('dump') # add a required argument parser_dump.add_argument(     'format',     choices=['csv', 'json'],     help='Dump the file in this format.')  #  subparser for upload parser_upload = subparsers.add_parser('upload') # add a required argument parser_upload.add_argument(     'server',     choices=['amazon', 'imgur'],     help='Upload the file to this service.')  args = parser.parse_args() print args if args.subcommand == 'dump':     print 'I will now dump "%s" in the %s format' % (args.file, args.format) if args.subcommand == 'upload':     print 'I will now upload "%s" to %s' % (args.file, args.server) 

That looks like this on the command line:

$ python ap.py  usage: ap.py [-h] file {upload,dump} ... ap.py: error: too few arguments $ python ap.py tmp.txt  usage: ap.py [-h] file {upload,dump} ... ap.py: error: too few arguments $ python ap.py tmp.txt upload usage: ap.py file upload [-h] {amazon,imgur} ap.py file upload: error: too few arguments $ python ap.py tmp.txt upload amazo usage: ap.py file upload [-h] {amazon,imgur} ap.py file upload: error: argument server: invalid choice: 'amazo' (choose from 'amazon', 'imgur') $ python ap.py tmp.txt upload amazon Namespace(file='tmp.txt', server='amazon', subcommand='upload') I will now upload "tmp.txt" to amazon $ python ap.py tmp.txt upload imgur Namespace(file='tmp.txt', server='imgur', subcommand='upload') I will now upload "tmp.txt" to imgur $ python ap.py tmp.txt dump usage: ap.py file dump [-h] {csv,json} ap.py file dump: error: too few arguments $ python ap.py tmp.txt dump csv Namespace(file='tmp.txt', format='csv', subcommand='dump') I will now dump "tmp.txt" in the csv format $ python ap.py tmp.txt dump json Namespace(file='tmp.txt', format='json', subcommand='dump') I will now dump "tmp.txt" in the json format 

More info: http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.add_subparsers

like image 79
Niels Bom Avatar answered Sep 21 '22 19:09

Niels Bom