Introduction
In this project you will build a Password Generator web app using Python and Streamlit. Users choose the password length and which character sets to include — lowercase, uppercase, numbers, symbols — and generate a strong random password in one click. Small utilities like this pair well — the age calculator is another single-purpose build.
Prerequisites
pip install streamlitStep 1: Create the Script
Create password_generator.py and paste the following:
import streamlit as st
import random
import string
st.set_page_config(page_title="Password Generator", page_icon="🔐")
st.title("🔐 Password Generator")
st.write("Generate a strong, secure password in one click.")
length = st.slider("Password Length", min_value=8, max_value=64, value=16)
col1, col2 = st.columns(2)
with col1:
use_lower = st.checkbox("Lowercase (a-z)", value=True)
use_upper = st.checkbox("Uppercase (A-Z)", value=True)
with col2:
use_digits = st.checkbox("Numbers (0-9)", value=True)
use_symbols = st.checkbox("Symbols (!@#$...)", value=True)
def generate_password(length, use_lower, use_upper, use_digits, use_symbols):
pool = ""
if use_lower: pool += string.ascii_lowercase
if use_upper: pool += string.ascii_uppercase
if use_digits: pool += string.digits
if use_symbols: pool += string.punctuation
return "".join(random.choice(pool) for _ in range(length)) if pool else None
if st.button("🔄 Generate Password"):
pwd = generate_password(length, use_lower, use_upper, use_digits, use_symbols)
if pwd:
st.text_input("Your Password:", value=pwd)
strength = sum([use_lower, use_upper, use_digits, use_symbols])
labels = ["Weak", "Fair", "Good", "Strong"]
st.progress(strength / 4, text=f"Strength: **{labels[strength - 1]}**")
st.success(f"✅ {length}-character password generated!")
else:
st.error("Select at least one character type.")Step 2: Run the App
streamlit run password_generator.pyStep 3: Use the App
How It Works
Security-wise, the app uses the `secrets` module, not random. Python's random is a Mersenne Twister — fast but *predictable* if you observe enough output. secrets uses the OS cryptographically secure generator, which is the only acceptable source for passwords and tokens.
Generation is a two-step: build a guaranteed-diverse base (one lowercase, one uppercase, one digit, one symbol) then fill the remaining length from the combined pool, and finally shuffle with secrets.SystemRandom().shuffle() so the guaranteed characters are not always first. The string module supplies the character classes cleanly.
The UI reads like a control panel: an st.slider for length, st.checkbox per character class, and st.metric or styled markdown showing entropy in bits. Entropy ≈ length × log2(pool_size) — a 16-character password from a 90-character pool is roughly 104 bits, far beyond brute-force reach.
Key Concepts
!@#$%^&*().Password Strength Guide
| Sets Enabled | Strength |
|---|---|
| 1 | Weak |
| 2 | Fair |
| 3 | Good |
| 4 | Strong |
What to Try Next
random.choice() for cryptographically secure output.0, O, l, and 1.Common Errors & Fixes
secrets.choice range logic; secrets.choice takes the *sequence* itself, e.g. secrets.choice(string.ascii_lowercase).st.code or a copy button instead.st.session_state.FAQ
Why secrets instead of random?
random is predictable from a few observed outputs; secrets draws from the OS entropy pool and is designed exactly for this use case.
What length should I use?
16+ characters mixing all four classes is a solid default. Length beats complexity: a 20-character password with fewer classes beats an 8-character one with all classes.
Can I generate passphrases instead?
Yes — pick 4-5 words from a wordlist with secrets.choice and join with hyphens; the entropy math is the same.