8

I need to hide password when user run script in console (like this: mysql -p). For input parameters I use argparse, how I can add getpass to password parameter?

parser = argparse.ArgumentParser()
parser.add_argument('-p', action='store', dest='password', type=getpass.getpass())

When I run my script: python script.py -u User -p I get separate line for enter password (Password:), but after entering Exception: ValueError: 'my_password' is not callable is raised.

martineau
  • 119,623
  • 25
  • 170
  • 301
oxana
  • 375
  • 1
  • 3
  • 10
  • 1
    its common to make a call to `getpass` after `argparse` parsing is complete so that its done after cmd line args have been verified. – tdelaney Apr 29 '15 at 16:05

4 Answers4

8

This guy should solve your problem: getpass

Here is an example with a custom action

class PwdAction(argparse.Action):

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

parser = argparse.ArgumentParser()
parser.add_argument('-f', action=PwdAction, nargs=0)
qwattash
  • 855
  • 7
  • 14
  • I use it (type=getpass.getpass()) but I need to use it together with argparse – oxana Apr 29 '15 at 15:50
  • Care to elaborate? OP is already using getpass. A link to the docs might be useful but it's not really an answer. – Holloway Apr 29 '15 at 15:53
  • 2
    Sorry, did't see. Then I'd create a custom action that prompts the user with getpass in there, let me edit the answer in a moment! – qwattash Apr 29 '15 at 15:56
  • 1
    Beat me to it. I've corrected mine anyway but this should be the accepted answer. – Holloway Apr 29 '15 at 16:28
7

EDIT: My previous answer was incorrect and based on a guess. This was my attempt at a working solution. @qwattash posted the answer correctly first but since I spent ten minutes working it out I thought I'd correct my answer.

import argparse
import getpass

class Password(argparse.Action):
    def __call__(self, parser, namespace, values, option_string):
        if values is None:
            values = getpass.getpass()
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument('-p', action=Password, nargs='?', dest='password')
args = parser.parse_args()

password = args.password #either from command line or from prompt
Holloway
  • 6,412
  • 1
  • 26
  • 33
  • I've tried, but in this case I take error: error: argument -p: expected one argument. In my solution at least I can run script and take line for input hidden password. – oxana Apr 29 '15 at 15:54
0

You should rename the process name. Maybe you are looking for this:

pip install setproctitle

https://github.com/dvarrazzo/py-setproctitle

Wotchin
  • 160
  • 6
-1

Short answer: No, you can't!

argparse module is not intend to do it. You should ask for the password on other separated process. Also, the type argument is just a value converter used before value is stored.

felipsmartins
  • 13,269
  • 4
  • 48
  • 56