Using Argparse to create required argument with multiple options?

If I understand Argparse correctly, the positional arguments are the required arguments that the user can specify. I need to create a positional argument with argparse where the user can specify a certain type of argument that is displayed if he/she brings up the -h option. I've tried using add_argument_group but it simply only displays a header with a description of the other arguments when you bring up the -h option.

def Main():
    parser = argparse.ArgumentParser(description = __doc__, formatter_class = argparse.RawDescriptionHelpFormatter)
    parser.add_argument("input_directory",help = "The input directory where all of the files reside in")

    sub_parser = parser.add_argument_group('File Type')

    sub_parser.add_argument(".txt",help = "The input file is a .txt file")
    sub_parser.add_argument(".n12",help = "The input file is a .n12 file")
    sub_parser.add_argument(".csv",help = "The input file is a .csv file")

    parser.parse_args()

if __name__ == "__main__":
    Main()

So when I run the script, I should specify in order to run the script. If I choose either .txt, .n12, or .csv as my argument, then the script should run. However, if the I don't specify the file type from those 3 options listed, then the script wouldn't run.

Is there an argparse function that I'm missing that can specify multiple options for a positional argument?

3 answers

  • answered 2018-02-13 03:57 Paul Cornelius

    I think you're making this too complicated. If I understand your problem correctly, you want the user to enter two arguments: a directory name and a file type. You application will accept only three values for file type. How about simply doing this:

    import argparse
    
    def Main():
        parser = argparse.ArgumentParser(description = __doc__, formatter_class = argparse.RawDescriptionHelpFormatter)
        parser.add_argument("input_directory", help = "The input directory where all of the files reside in")
        parser.add_argument("file_type", help="One of: .txt, .n12, .csv")
        args = parser.parse_args()
        print(args)
    
    if __name__ == "__main__":
        Main()
    

    ... and adding application logic to reject invalid values for file type.

    You access the user-entered values through the object returned by parse_args().

  • answered 2018-02-13 04:11 Robᵩ

    Use the choices= parameter to force the user to choose from a restricted set of values.

    import argparse
    
    def Main():
        parser = argparse.ArgumentParser()
        parser.add_argument("input_directory",help = "The input directory where all of the files reside in")
        parser.add_argument("file_type", help = "File Type", choices=['.txt', '.n12', '.csv'])
    
        ns = parser.parse_args()
        print(ns)
    
    
    if __name__ == "__main__":
        Main()
    

  • answered 2018-02-13 04:12 Saket Mittal

    Use option grouping feature use add_mutually_exclusive_group() instead of add_argument_group()

    import argparse
    
    
    def Main():
        parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
        parser.add_argument("input_directory", help="The input directory where all of the files reside in")
    
        group = parser.add_mutually_exclusive_group(required=True)
        group.add_argument("-txt", action='store_true', help="The input file is a .txt file")
        group.add_argument("-n12", action='store_true', help="The input file is a .n12 file")
        group.add_argument("-csv", action='store_true', help="The input file is a .csv file")
    
        print parser.parse_args()
    
    if __name__ == "__main__":
        Main()