Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Using getpass with argparse

I've had a look around, but couldn't find anything.

Basically I was wondering if it was possible to use getpass.getpass() with argparse.

At the moment I have the following as a work around, I was just wondering if there was a better way:

import argparse
import getpass

parser = argparse.ArgumentParser(description="Some description")
parser.add_argument('-p', metavar="password", default="foobarblah123", help="password for user (default to prompt user)")
...
parsed_args = parser.parse_args()
args = vars(parsed_args)
user_pass = args['p']
if user_pass == "foobarblah123":
  user_pass = getpass.getpass()

I'm pretty sure this is not the best way to handle this, however, there is a requirement to have a command line option for the password ... best practice or not.

Thanks.

like image 627
MHibbin Avatar asked Jan 13 '15 11:01

MHibbin


People also ask

How do I use Getpass in Python?

Using getpass() function to prompt user passwordThe getpass() function is used to prompt to users using the string prompt and reads the input from the user as Password. The input read defaults to “Password: ” is returned to the caller as a string. Here, no prompt is provided by the caller.

Is Getpass in Python standard library?

There are two functions defined in getpass module of Python's standard library. They are useful whenever a terminal based application needs to be executed only after validating user credentials.

What is Getpass library in Python?

The getpass module provides a platform-independent way to enter a password in a command-line program, as Example 2-25 shows. getpass(prompt) prints the prompt string, switches off keyboard echo, and reads a password. If the prompt argument is omitted, it prints " Password: “.


2 Answers

I think I might have found a nicer way to do it. How about using a custom Action like this:

import argparse
import getpass

class PasswordPromptAction(argparse.Action):
    def __init__(self,
             option_strings,
             dest=None,
             nargs=0,
             default=None,
             required=False,
             type=None,
             metavar=None,
             help=None):
        super(PasswordPromptAction, self).__init__(
             option_strings=option_strings,
             dest=dest,
             nargs=nargs,
             default=default,
             required=required,
             metavar=metavar,
             type=type,
             help=help)

    def __call__(self, parser, args, values, option_string=None):
        password = getpass.getpass()
        setattr(args, self.dest, password)

parser.add_argument('-u', dest='user', type=str, required=True)
parser.add_argument('-p', dest='password', action=PasswordPromptAction, type=str, required=True)

args = parser.parse_args()
like image 189
Rares Musina Avatar answered Sep 16 '22 12:09

Rares Musina


After looking around and not finding a sufficient solution. Here is what I came up with.

from argparse import ArgumentParser
from getpass import getpass

def main():
    parser = ArgumentParser(description="arg parser hidden password input.")
    parser.add_argument('-sp', '--secure_password', action='store_true', dest='password', 
                        help='hidden password prompt')
    args=parser.parse_args()

    if args.password:
        password = getpass()

    print(password)

if __name__ == "__main__":
    main()

Obviously you would want to remove print(password), this is just added to verify it works.

like image 23
lwelna Avatar answered Sep 17 '22 12:09

lwelna