-1

Below scripts prints an output as well as opens a webpage based on command line arguments.

#main.py

import os, numpy
import argparse
import webbrowser

new=2

def main():
    parser = argparse.ArgumentParser() 
    parser.add_argument('-i','--input',type=str, help='Choose input')
    parser.add_argument('-d','--display',dest='disp',type=str, help='Opens a webpage', default=None)

    args = parser.parse_args()
 
    if args.input == 'infile':
        print('This is input file')

    if args.disp == 'openbrowser':
        url = "https://stackoverflow.com/"
        webbrowser.open(url,new=new,autoraise=True)
     
if __name__=='__main__':
    main()

If I use the following command:

python3 main.py --input infile --display openbrowser

The desired output is attained. But, I would like --display (ideally without any str) to be parsed along with --input as a sub-command and not as a separate optional flag argument -d. The flag -display is only used if --input is used as the primary flag, and even --display should be optional in itself and shouldn't be obligatory.

So I would like the command line arguments to look like:

python3 main.py --input infile --display

This prints This is input file and opens webpage in the browser. and

python3 main.py --input infile 

This prints the output This is input file only

newstudent
  • 402
  • 6
  • 19

2 Answers2

1

You're looking for the action='store_true' property on the argument specification. https://docs.python.org/3/library/argparse.html#action

parser.add_argument('-d', '--display', dest='disp',
                    action='store_true', help='Opens a webpage')
#main.py

import os, numpy
import argparse
import webbrowser

new=2

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-i','--input',type=str, help='Choose input')
    parser.add_argument('-d','--display',dest='disp', action='store_true', help='Opens a webpage')

    args = parser.parse_args()

    if args.input == 'infile':
        print('This is input file')

    if args.disp:
        url = "https://stackoverflow.com/"
        webbrowser.open(url,new=new,autoraise=True)

if __name__=='__main__':
    main()
lwohlhart
  • 1,829
  • 12
  • 20
  • thanks, although this answer works I was thinking if there is a possibility to do the task via using `sub-parsers` where `-d` is dependent on `--input`. – newstudent Jul 01 '22 at 17:51
1

This should be exactly what you are looking for.

In order to add subcommands you use the ArgumentParser.add_subparsers method which requires no parameters and returns an object that can create as many subcommands as you would like.

import os, numpy
import argparse
import webbrowser

new=2

def main():
    parser = argparse.ArgumentParser() 

    subparsers = parser.add_subparsers()
    input_parser = subparsers.add_parser("input")
    input_parser.add_argument('filename', help='path to file')
    args = parser.parse_args()
        input_parser.add_argument(
        '-d',
        '--display',
        dest='disp', 
        action='stor_true',  
        help='Opens a webpage'
     )

    if 'filename' in args:
        print('This is input file')
    if args.disp:
        url = "https://stackoverflow.com/"
        webbrowser.open(url,new=new,autoraise=True)
     
if __name__=='__main__':
    main()
Alexander
  • 16,091
  • 5
  • 13
  • 29
  • @I dont think this works with `python3 main.py --input filename --display`. Also I would like --input to be optional rather than positional argument – newstudent Jul 04 '22 at 07:19
  • @newstudent You said you wanted input to be a subcommand subcommands dont have prefix characters – Alexander Jul 04 '22 at 07:23
  • I said I wanted --display to be the sub-command of --input, I've did write the command line arguments in my post – newstudent Jul 04 '22 at 07:24
  • 1
    @newstudent You have a misunderstanding of how command line options work. anything that starts with the prefix character `-` is an option flag. Option flags don't have subcommands, but subcommands can have option flags. – Alexander Jul 04 '22 at 07:28
  • @newstudent I edited my answer... It now should operate the way you want, other than input doesn't have the prefix character also iwohlhart answer is also very similar – Alexander Jul 04 '22 at 07:32