Skip to content

Instantly share code, notes, and snippets.

@syntaxhacker
Created July 30, 2026 08:20
Show Gist options
  • Select an option

  • Save syntaxhacker/64c08edee9e1e24a698e0e056a5899ac to your computer and use it in GitHub Desktop.

Select an option

Save syntaxhacker/64c08edee9e1e24a698e0e056a5899ac to your computer and use it in GitHub Desktop.
Gmail SMTP/IMAP integration with Python using App Password — send with attachments, read unread emails, no OAuth setup required

Gmail Integration with Python (SMTP + IMAP)

A working setup to send and read Gmail programmatically using Python, without browser automation or OAuth setup — just an App Password.

Prerequisites

Setup

1. Generate an App Password

  1. Go to https://myaccount.google.com/apppasswords
  2. Select "Mail" and your device
  3. Copy the 16-char password (e.g. jfff kdzn llka srvw)

2. Set Environment Variables

export GMAIL_EMAIL="your.email@gmail.com"
export GMAIL_APP_PASSWORD="jfff kdzn llka srvw"

Sending Email (SMTP)

import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

def send_email(sender, password, to, subject, body, attachment_path=None):
    msg = MIMEMultipart("alternative")
    msg["From"] = sender
    msg["To"] = to
    msg["Subject"] = subject
    msg.attach(MIMEText(body, "plain"))

    if attachment_path and os.path.exists(attachment_path):
        part = MIMEBase("application", "octet-stream")
        with open(attachment_path, "rb") as f:
            part.set_payload(f.read())
        encoders.encode_base64(part)
        part.add_header("Content-Disposition",
            f'attachment; filename="{os.path.basename(attachment_path)}"')
        msg.attach(part)

    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.starttls()
    server.login(sender, password)
    server.send_message(msg)
    server.quit()

send_email("your.email@gmail.com", "jfff kdzn llka srvw",
           "recipient@example.com", "Subject", "Body",
           "/path/to/resume.pdf")

Reading Unread Email (IMAP)

import imaplib, email
from email.header import decode_header

mail = imaplib.IMAP4_SSL("imap.gmail.com")
mail.login("your.email@gmail.com", "jfff kdzn llka srvw")
mail.select("inbox")

status, ids = mail.search(None, "UNSEEN")
ids = ids[0].split()[-5:] if ids[0] else []
ids.reverse()

for eid in ids:
    status, data = mail.fetch(eid, "(RFC822)")
    msg = email.message_from_bytes(data[0][1])
    subject, enc = decode_header(msg["Subject"])[0]
    if isinstance(subject, bytes):
        subject = subject.decode(enc or "utf-8", errors="replace")
    print(f"From: {msg['From']}")
    print(f"Subject: {subject}")
    print(f"Date: {msg['Date']}")

mail.logout()

Key Details

Item Value
SMTP Server smtp.gmail.com:587 (STARTTLS)
IMAP Server imap.gmail.com:993 (SSL)
Auth Full email + App Password (not regular password)
App Password format 16 chars, space-separated groups of 4

Why App Password over OAuth?

Approach Pros Cons
App Password Simple, no OAuth flow, immediate Requires 2FA, single-purpose
OAuth 2.0 More secure, no 2FA required Setup complexity, refresh tokens

Full Script

Full working script at: /home/mysyntax/Documents/me_2025/send_email.py

It handles:

  • CLI args: recipient, subject, body
  • Interactive prompts when args missing
  • Env var or prompted credentials
  • Resume PDF attachment
import os
import sys
import smtplib
import mimetypes
from email.message import EmailMessage
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email import encoders
GMAIL_SMTP = "smtp.gmail.com"
GMAIL_PORT = 587
RESUME_PATH = os.path.join(os.path.dirname(__file__), "public", "rohit_jogi_resume.pdf")
DEFAULT_SUBJECT = "Application for Software Engineering Position"
DEFAULT_BODY = """Hi,
I'm Rohit Jogi, a Senior Full Stack Developer with 5+ years of experience building scalable web applications using React, Node.js, Python, and cloud infrastructure on AWS.
I'm reaching out regarding software engineering opportunities at your organization. My background includes leading frontend architecture, building RESTful APIs, and managing cloud deployments.
Please find my resume attached. I'd welcome the chance to discuss how my experience aligns with your team's needs.
Best regards,
Rohit Jogi
+91-9582633422
rohitjogi.datascience@gmail.com
github.com/rohitjogi
linkedin.com/in/rohit--jogi"""
def get_credentials():
email = os.environ.get("GMAIL_EMAIL") or os.environ.get("EMAIL")
password = os.environ.get("GMAIL_APP_PASSWORD") or os.environ.get("APP_PASSWORD")
if not email:
email = input("Enter your Gmail address: ").strip()
if not password:
import getpass
password = getpass.getpass("Enter your Gmail App Password: ").strip()
return email, password
def compose_message(to_email, subject, body, resume_path):
msg = MIMEMultipart("alternative")
msg["From"] = sender_email
msg["To"] = to_email
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))
if resume_path and os.path.exists(resume_path):
part = MIMEBase("application", "octet-stream")
with open(resume_path, "rb") as f:
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", f'attachment; filename="{os.path.basename(resume_path)}"')
msg.attach(part)
return msg
def send_email(sender, password, to_email, subject, body, resume_path=None):
msg = compose_message(to_email, subject, body, resume_path)
msg["From"] = sender
server = smtplib.SMTP(GMAIL_SMTP, GMAIL_PORT)
server.starttls()
server.login(sender, password)
server.send_message(msg)
server.quit()
if __name__ == "__main__":
to = sys.argv[1] if len(sys.argv) > 1 else None
subject = sys.argv[2] if len(sys.argv) > 2 else DEFAULT_SUBJECT
body = sys.argv[3] if len(sys.argv) > 3 else DEFAULT_BODY
if not to:
to = input("Recipient email: ").strip()
sender_email, password = get_credentials()
print(f"Sending to {to}...")
send_email(sender_email, password, to, subject, body, RESUME_PATH)
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment