How to Download Gmail Attachments Using Python

Learn how to download Gmail attachments with Python using ezgmail. Follow this easy step-by-step guide for beginners and automate your inbox today.

Need to quickly download Gmail attachments without opening each email manually? Whether it’s invoices, resumes, or memes โ€” you can automate it all with Python. In this beginner-friendly guide, Iโ€™ll walk you through a simple script to search Gmail and bulk-download attachments in just a few steps.


๐Ÿง  What Youโ€™ll Learn

  • How to use the ezgmail Python library
  • Search emails with attachments using Gmail queries
  • Download attachments from Gmail threads
  • Build a complete command-line script, even as a beginner

๐Ÿ”ง Prerequisites

Before diving in, make sure youโ€™ve got:

โœ… Python 3 installed
โœ… A Gmail account
โœ… Basic knowledge of Python
โœ… Some command-line comfort

Youโ€™ll also need to install and set up ezgmail, a beginner-friendly library for Gmail automation.


๐Ÿ“ฆ Step 1: Install ezgmail

Open your terminal and run:

pip install ezgmail

๐Ÿ” Step 2: Set Up Gmail API Access (First-Time Only)

  1. Go to the Google Developer Console.
  2. Create a project.
  3. Enable the Gmail API.
  4. Create OAuth client ID credentials.
  5. Download the credentials.json file and save it in your project folder.
  6. Run this once to authenticate:
import ezgmail
ezgmail.init()

This creates a token.json file for future access.

โœ… Now youโ€™re ready to automate Gmail!


๐Ÿงพ Step 3: The Complete Script

Hereโ€™s the full Python code, explained step-by-step:

import ezgmail

We import the ezgmail library to access Gmail through Python.


๐Ÿ“ Step 4: Define the Attachment Downloader Function

def attachmentdownload(resulthreads):

This function takes Gmail search results as input.

    countofresults = len(resulthreads)

We count how many threads (conversations) matched the query.


๐Ÿ” Loop Through Threads and Messages

    try:
for i in range(countofresults):

Loop through each thread.

            if len(resulthreads[i].messages) > 1:

If the thread has multiple messages (a long conversation):

                for j in range(len(resulthreads[i].messages)):
resulthreads[i].messages[j].downloadAllAttachments()

Loop through each message in the thread and download attachments.

           else:
resulthreads[i].messages[0].downloadAllAttachments()

If the thread has only one message, just download that one.

        print("Download complete. Please check your root directory.")

Prints a success message.

    except:
raise Exception("Error occurred while downloading attachment(s).")

Handles any unexpected errors during download.


๐Ÿ“ฅ Step 5: The Main Script

if __name__ == '__main__':

Standard Python entry point.

    query = input("Enter search query: ")

Ask the user for a Gmail search query (like "from:boss@example.com" or "subject:invoice").

    newquery = query + " + has:attachment"

We force Gmail to only return emails with attachments using has:attachment.

๐Ÿ“ Learn more Gmail search operators here.


๐Ÿ” Step 6: Search for Matching Emails

    resulthreads = ezgmail.search(newquery)

Search Gmail with our updated query.

    if len(resulthreads) == 0:
print("Result has no attachments:")

No matches? Let the user know.

    else:
print("Result(s) with attachments:")

Found something? Letโ€™s show the subject line for each email.

        for threads in resulthreads:
print(f"Email Subject: {threads.messages[0].subject}")

Print the subject of the first message in each thread.


๐Ÿ“Ž Step 7: Ask User Before Downloading

        try:
ask = input("Do you want to download attachment(s) in result(s) (Yes/No)? ")

Get user confirmation.

            if ask == "Yes":
attachmentdownload(resulthreads)
else:
print("Program exited")

If “Yes”, download. Otherwise, exit politely.

        except:
print("Something went wrong")

Catch unexpected errors.


๐Ÿ“ฆ Full Script Recap

import ezgmail


def attachmentdownload(resulthreads):
countofresults = len(resulthreads)
try:
for i in range(countofresults):
if len(resulthreads[i].messages) > 1:
for j in range(len(resulthreads[i].messages)):
resulthreads[i].messages[j].downloadAllAttachments()
else:
resulthreads[i].messages[0].downloadAllAttachments()
print("Download complete. Please check your root directory.")
except:
raise Exception("Error occurred while downloading attachment(s).")


if __name__ == '__main__':
query = input("Enter search query: ")
newquery = query + " + has:attachment"
resulthreads = ezgmail.search(newquery)

if len(resulthreads) == 0:
print("Result has no attachments:")
else:
print("Result(s) with attachments:")
for threads in resulthreads:
print(f"Email Subject: {threads.messages[0].subject}")
try:
ask = input("Do you want to download attachment(s) in result(s) (Yes/No)? ")
if ask == "Yes":
attachmentdownload(resulthreads)
else:
print("Program exited")
except:
print("Something went wrong")

๐Ÿ“ Where Are My Attachments Saved?

By default, theyโ€™re downloaded to the current directory where you run the script. You can easily change the download path in downloadAllAttachments() if needed.


๐Ÿ’ก Pro Tips

  • Use precise Gmail queries like subject:"invoice" after:2025/01/01.
  • You can modify the script to filter by file type or sender.
  • Want to download from a label? Use label:your-label.

๐Ÿง  Wrapping Up

This tiny script can save hours of manual downloading if you get lots of attachments โ€” whether itโ€™s for work, taxes, or even memes ๐Ÿ˜„

Youโ€™ve now:

  • Connected Python to Gmail
  • Fetched emails with attachments
  • Downloaded everything with one click

๐Ÿ‘‰ Whatโ€™s Next?

If you loved this, check out our other Python automation tutorials:


๐Ÿ›  Want Us to Automate Your Inbox?

Explore Ossels AIโ€™s Services โ€” we help businesses automate everything with smart, scalable AI.


๐Ÿ’ฌ Got questions? Drop them in the comments or ping us on Instagram. Letโ€™s automate smart!

Posted by Ananya Rajeev

Ananya Rajeev is a Kerala-born data scientist and AI enthusiast who simplifies generative and agentic AI for curious minds. B.Tech grad, code lover, and storyteller at heart.