"""Gravatar URL helper. Pure function — no HTTP calls. The browser does the actual image fetch. We just build the deterministic URL from the user's email and let Gravatar serve an identicon when no account exists for that hash, so the avatar is never a broken image. Current Gravatar guidance is SHA-256 of the trimmed, lower-cased email. MD5 still works but is deprecated, so we prefer SHA-256. """ import hashlib from typing import Optional def gravatar_url(email: Optional[str], size: int = 240) -> Optional[str]: """Return a Gravatar image URL for `email`, or None when email is empty. The `d=identicon` fallback guarantees a deterministic placeholder when the address has no Gravatar account, so callers can treat the result as a valid image URL. """ if not email: return None normalized = email.strip().lower() if not normalized: return None digest = hashlib.sha256(normalized.encode("utf-8")).hexdigest() return f"https://gravatar.com/avatar/{digest}?d=identicon&s={size}"