Last active
June 6, 2025 21:43
-
-
Save scivision/12d4177b743fafc9e5ff37d14bd44e8d to your computer and use it in GitHub Desktop.
Extract attachements from .eml email downloaded file from GMail, email client, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Use Python stdlib "email" to extract attachments from an .eml file | |
as obtained from an email client or Download from Gmail etc. | |
based on https://gist.github.com/urschrei/5258588 | |
""" | |
from pathlib import Path | |
import email | |
import email.policy | |
import email.message | |
import argparse | |
import logging | |
def extract_payload(att: email.message.EmailMessage, extract_dir: Path) -> Path | None: | |
try: | |
outfn = att.get_filename() | |
except AttributeError: | |
logging.error(f"Could not get attachment filename") | |
return None | |
if not outfn: | |
logging.error(f"Attachment has no filename") | |
return None | |
outpath = extract_dir / outfn | |
with outpath.open("wb") as of: | |
try: | |
if pd := att.get_payload(decode=True): | |
of.write(pd) # type: ignore | |
return outpath | |
except TypeError: | |
logging.error(f"Couldn't get payload for {outfn}") | |
return None | |
def extract_attachments(fn: Path, extract_dir: Path) -> None: | |
count = 0 | |
with fn.open("r") as f: | |
msg = email.message_from_file(f, policy=email.policy.default) | |
for att in msg.iter_attachments(): | |
if outpath := extract_payload(att, extract_dir): | |
count += 1 | |
print(f"Extracted {outpath}") | |
if count == 0: | |
raise ValueError(f"No attachment found for file {f.name}") | |
if __name__ == "__main__": | |
p = argparse.ArgumentParser(description="extract attachments from .eml file") | |
p.add_argument("file", help=".eml file to extract attachments from") | |
p.add_argument( | |
"-extract_dir", help="directory to extract attachment to", default="." | |
) | |
P = p.parse_args() | |
eml = Path(P.file).expanduser() | |
extract_attachments(eml, Path(P.extract_dir).expanduser().resolve(strict=True)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment