0

I'm writing a simple script that will be used parse the contents of a JSON file stored on AWS CloudWatch. I've added an argument parser to the script that will accept user input, and allow the user to either print the output of the file to the screen (in a predetermined fashion), or allow them to output the contents to a local JSON file. Here's a snippet of what's stumping me:

import argparse

parser = argparse.ArgumentParser(description="Process a log file")
parser.add_argument('-o', '--output', choices=[???, 'print'], 
                    default='print', help='Specify logfile output path or print to screen')
args = parser.parse_args()

My question stems from the parser.add_argument line, specifically the choices argument. I'd like to allow two inputs for this flag, those being either print or some valid path on their local machine. I'd like the choice that's currently marked by question marks to be a PATH that Python can recognize.

Is there a way, using argparse, to specify that one of of the arguments to a flag must be a PATH? Search results have been, so far, inconclusive.

Thanks in advance!

nat5142
  • 485
  • 9
  • 21
  • The value for `choices` can be any list of strings. I suggest using an `os` function to fetch the list of valid paths, manipulate it if needed, add 'print' to, and then set up `add_argument`. Another option is to accept any string (no choices), and do the testing after parsing. – hpaulj Jun 12 '18 at 18:56
  • In my opinion, you shouldn't use `choices` option. There's a function to check if a path is valid or not ([see here](https://stackoverflow.com/questions/9532499/check-whether-a-path-is-valid-in-python-without-creating-a-file-at-the-paths-ta)). To me, you should just check the value of the flag you're receiving. As you should *always* do anyways. – IMCoins Jun 12 '18 at 18:58
  • `choices` will be a problem if the list is long - display in help and error messages gets messy. – hpaulj Jun 12 '18 at 19:44

2 Answers2

6

Use the type keyword argument to add_argument, instead of choices. As the documentation says:

The type keyword argument of add_argument() allows any necessary type-checking and type conversions to be performed.

def myfiletype(arg):
    if arg == 'print' or os.path.isdir(arg):
        return arg
    else:
        raise ValueError('Invalid path specification')


parser.add_argument('-o', '--output', type=myfiletype, 
                    default='print', 
                    help='Specify logfile output path or print to screen')
nosklo
  • 217,122
  • 57
  • 293
  • 297
0

Define a custom type (as in https://stackoverflow.com/a/14117511/1093967), where the value can be a valid path or 'print'. choices isn't the right choice here.

deepyaman
  • 538
  • 5
  • 16