PyMOTW: getpass
Module: getpass
Purpose: Prompt the user for a value, usually a password, without echoing what they type to the console.
Python Version: 1.5.2
Description:
Many programs which interact with the user via the terminal need to ask the user for password values without showing what the user types on the screen. The getpass module provides a portable way to handle such password prompts securely.
Example:
The getpass() function prints a prompt then reads input from the user until they press return. The input is passed back as a string to the caller.
import getpass
p = getpass.getpass()
print 'You entered:', p
The default prompt, if none is specified by the caller, is "Password:".
$ python getpass_defaults.py
Password:
You entered: sekret
Of course the prompt can be anything your program needs.
p = getpass.getpass(prompt='What is your favorite color? ')
if p.lower() == 'blue':
print 'Right. Off you go.'
else:
print 'Auuuuugh!'
I don't recommend such an insecure authentication scheme, but it illustrates the point.
$ python getpass_prompt.py
What is your favorite color?
Right. Off you go.
$ python getpass_prompt.py
What is your favorite color?
Auuuuugh!
By default, getpass() uses stdout to print the prompt string. For a program which may produce useful output on sys.stdout, it is useful to send the prompt to another stream such as sys.stderr.
import getpass
import sys
p = getpass.getpass(stream=sys.stderr)
print 'You entered:', p
This way standard output can be redirected (to a pipe or file) without seeing the password prompt. The value entered by the user is still not echoed back to the screen.
$ python getpass_stream.py >/dev/null
Password:
Using getpass Without a Terminal
Under Unix, getpass() always requires a tty it can control via termios, so echo can be disabled. This means values will not be read from a non-terminal stream redirected to standard input.
$ echo "sekret" | python getpass_defaults.py
Traceback (most recent call last):
File "getpass_defaults.py", line 34, in
p = getpass.getpass()
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/getpass.py", line 32, in unix_getpass
old = termios.tcgetattr(fd) # a copy to save
termios.error: (25, 'Inappropriate ioctl for device')
It is up to the caller to detect when the input stream is not a tty and use an alternate method for reading in that case.
import getpass
import os
import sys
if os.isatty(sys.stdin.fileno()):
p = getpass.getpass('Using getpass: ')
else:
print 'Using readline'
p = sys.stdin.readline().rstrip()
print 'Read: ', p
With a tty:
$ python ./getpass_noterminal.py
Using getpass:
Read: sekret
Without a tty:
$ echo "sekret" | python ./getpass_noterminal.py
Using readline
Read: sekret
References:
Python Module of the Week Home
Download Sample Code
Technorati Tags:
python, PyMOTW

3 comments:
I think "os.isatty(sys.stdin.fileno())" could be written more nicely as "sys.stdin.isatty()".
You're absolutely right. Thanks for the tip!
Hey man,
Your snippit regarding the os.isatty is perfect. Thanks! Turns out Eclipse's debugging console is not treated as a TTY when using getpass.getpass(). This works perfectly, thanks again!
Post a Comment