Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine interactive prompting with argparse in python?

I've got a program with a large number of potential args. It basically allows the user to get/set/delete/list any table in a very small database. Each column has a arg that can be passed.
This isn't the main interface, just an occasionally useful admin interface.

Anyhow, if the user wants to insert a row into a table he has to know the name of all the columns. While it's easy to see that from the help - it's also a pain in the butt.

So, I've changed the code so the user can pass a --prompt option and the program will prompt them for every column name associated with the table they specified. But my problem is that I now need to duplicate my input constraints (choices, types, etc) in two places - argparse and this prompting function.

  • Question #1: is there a better way of doing this?
  • Question #2: is there a clean way to reference argparse constraints for this purpose?
  • Question #3: are there any libraries recommended as alternatives that combine command line args, options and prompting?

Thanks

like image 398
KenFar Avatar asked Jun 11 '12 04:06

KenFar


1 Answers

A typical way to do this would be with a custom action. You can have the argparse option and the input validated with the same function like this.

#!/usr/bin/env python3

import argparse


class ColumnsAction(argparse.Action):
    def __call__(self, parser, namespace, value, option_string=None):
        self.validate(parser, value)
        setattr(namespace, self.dest, value)

    @staticmethod
    def validate(parser, value):
        if value not in ('foo', 'bar'):
            parser.error('{} not valid column'.format(value))


parser = argparse.ArgumentParser()
parser.add_argument('--columns', action=ColumnsAction)
args = parser.parse_args()
if args.columns is None:
    args.columns = input('Enter columns: ')
    ColumnsAction.validate(parser, args.columns)
print(args.columns)
like image 100
mgbelisle Avatar answered Nov 04 '22 11:11

mgbelisle