The getpass module provides secure password input—characters aren't echoed to the terminal. Simple but essential for CLI tools.
Basic Password Input
import getpass
password = getpass.getpass()
# Prompts: "Password: " (input hidden)
# Custom prompt
password = getpass.getpass("Enter your secret: ")The input isn't echoed—no characters appear as you type.
Get Current Username
import getpass
username = getpass.getuser()
print(f"Current user: {username}")
# Gets from LOGNAME, USER, LNAME, USERNAME env vars
# Falls back to pwd module on UnixPractical Examples
Login Prompt
import getpass
def login():
username = input("Username: ")
password = getpass.getpass("Password: ")
if authenticate(username, password):
print("Login successful")
else:
print("Invalid credentials")
def authenticate(username, password):
# Your auth logic here
return username == "admin" and password == "secret"Database Connection
import getpass
def connect_db():
host = input("Host [localhost]: ") or "localhost"
user = input(f"User [{getpass.getuser()}]: ") or getpass.getuser()
password = getpass.getpass()
database = input("Database: ")
return {
'host': host,
'user': user,
'password': password,
'database': database,
}API Key Input
import getpass
import os
def get_api_key():
# Check environment first
key = os.environ.get('API_KEY')
if key:
return key
# Prompt securely
return getpass.getpass("API Key: ")Sudo-Style Confirmation
import getpass
def confirm_action(action: str) -> bool:
print(f"This will {action}")
password = getpass.getpass(f"[sudo] password for {getpass.getuser()}: ")
return verify_password(password)Handling Non-TTY Input
When stdin isn't a terminal (piped input), getpass warns and may fail:
import getpass
import sys
def safe_getpass(prompt="Password: "):
if sys.stdin.isatty():
return getpass.getpass(prompt)
else:
# Fallback for non-interactive
print(prompt, end='', file=sys.stderr)
return sys.stdin.readline().rstrip('\n')With Environment Variables
import getpass
import os
def get_credentials():
"""Get credentials from env or prompt."""
username = os.environ.get('APP_USER')
password = os.environ.get('APP_PASSWORD')
if not username:
username = input("Username: ")
if not password:
password = getpass.getpass()
return username, passwordMasked Input Alternative
getpass shows nothing. For asterisks, you need more code:
import sys
def getpass_masked(prompt="Password: "):
"""Show asterisks as user types."""
if sys.platform == 'win32':
import msvcrt
print(prompt, end='', flush=True)
chars = []
while True:
char = msvcrt.getwch()
if char in ('\r', '\n'):
print()
return ''.join(chars)
elif char == '\x08': # Backspace
if chars:
chars.pop()
print('\b \b', end='', flush=True)
else:
chars.append(char)
print('*', end='', flush=True)
else:
# Unix: use getpass (no easy masking)
import getpass
return getpass.getpass(prompt)Security Considerations
import getpass
# Password is still in memory as a string
password = getpass.getpass()
# Clear after use (helps, but not guaranteed)
# Python strings are immutable, so this creates a new object
password = None
# For high-security apps, consider:
# - Using SecureString equivalents if available
# - Hashing immediately after input
# - Using memory-safe languages for auth handlingTesting Code with getpass
import getpass
from unittest.mock import patch
def login(username, password):
return username == "admin" and password == "secret"
def main():
username = input("Username: ")
password = getpass.getpass()
return login(username, password)
# Test
def test_login():
with patch('builtins.input', return_value='admin'):
with patch('getpass.getpass', return_value='secret'):
assert main() == TrueQuick Reference
import getpass
# Secure password input (no echo)
password = getpass.getpass()
password = getpass.getpass("Custom prompt: ")
# Get current username
username = getpass.getuser()| Function | Purpose |
|---|---|
getpass() | Read password without echo |
getuser() | Get current username |
That's it—two functions. getpass does one thing well: hide password input. Use it for any CLI that needs credentials.
React to this post: