import argparse import sys import requests def find_email(username: str, token: str | None = None) -> str | None: headers = {"Accept": "application/vnd.github+json"} if token: headers["Authorization"] = f"Bearer {token}" url = f"https://api.github.com/users/{username}/events/public" try: resp = requests.get(url, headers=headers, timeout=10) except requests.RequestException as e: print(f"Network error: {e}", file=sys.stderr) return None if resp.status_code == 404: print(f"User '{username}' not found.", file=sys.stderr) return None if resp.status_code == 403: print("Rate limited by GitHub API. Try again later or use --token.", file=sys.stderr) return None if resp.status_code != 200: print(f"GitHub API error: {resp.status_code} {resp.text}", file=sys.stderr) return None events = resp.json() for event in events: if event.get("type") != "PushEvent": continue commits = event.get("payload", {}).get("commits", []) for commit in commits: author = commit.get("author", {}) email = author.get("email") name = author.get("name", "") if not email: continue if "noreply.github.com" in email: continue print(f"Found: {name} <{email}> (from a push event)") return email print(f"No public email found for '{username}'.", file=sys.stderr) print( "This can happen if the user has enabled 'Keep my email addresses " "private', has no recent public push events, or only committed " "using a noreply address.", file=sys.stderr, ) return None def main(): parser = argparse.ArgumentParser(description="Find a GitHub user's public commit email.") parser.add_argument("username", help="GitHub username to look up") parser.add_argument("--token", help="GitHub personal access token (optional, raises rate limits)") args = parser.parse_args() email = find_email(args.username, args.token) if email: print(email) sys.exit(0) else: sys.exit(1) if __name__ == "__main__": main()