Python Forum
smtplib : name of attachment wrongly set to default
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
smtplib : name of attachment wrongly set to default
#1
Hi

I wrote a python script to create and send pdf files with "smtplib". I'm creating these files from a template html file with "beautiful soap". I convert them to pdf with "xhtml2pdf".

In the resulting e-mail the name of the attachment is not always correctly set. It is sometime set to "default", instead of the file name.

I ran several tests with various names (hereunder pj0 and pj1). Runing pj0 gets a correct attachment name. Running pj1 gets "default". I have not been able to find what is wrong.

The code to attach the files and set the attachment name is as follows :

def smtp () :
	msg = MIMEMultipart()
	
# Compléter l'entête
	msg['Subject'] = ''
	msg['From'] = ''
	msg['To'] = ''
	texte_message =''
	msg.attach(MIMEText(gbl.objets['texte_message'], 'plain'))
	
# Insérer la pièce jointe
	part = MIMEBase('application', 'pdf')
	html_template = ''
	p_jointe = btfs(html_template, 'html.parser')
# I ran several test, commenting the appropriate lines
	pj0 = '/home/arbiel/Téléchargements/ANNEXES 1 A 5.pdf'
	pj1 = '/home/arbiel/Téléchargements/Quittance N°132 (123 €).pdf'

#	with open(pj0, "rb") as f:
#		part.set_payload(f.read())
#	encoders.encode_base64(part)
#	part.add_header(
#		'Content-Disposition',
#		f'attachment; filename="{pj0.split("/")[-1]}"',
#	)   
#	msg.attach(part)


#	convert p_jointe to pdf into pj1
	with open(pj1, "rb") as f:
		part.set_payload(f.read())
	encoders.encode_base64(part)
	part.add_header(
		'Content-Disposition',
		f'attachment; filename="{pj1.split("/")[-1]}',
	)   
	msg.attach(part)
	
# contacter le serveur
	mailServer = smtplib.SMTP('outgoing_server','outgoing_port')
	s = mailServer.login('sender_email', send_password')
	
# envoyer le courriel
	mailServer.send_message(msg)
	mailServer.close()
	
using Ubuntu 22.04.5 LTS, Python 3.10.12
having substituted «https://www.lilo.org/fr/» to google, «https://protonmail.com/» to any other unsafe mail service and bépo to azerty (french keyboard layouts)
Reply
#2
I suggest you make the PDFs first, then attach them. That way you know that you have a good PDF before trying to send it! Then open 'rb'.

This worked for me last time I used it.

#! /usr/bin/python3
import email, smtplib, ssl
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate

path2pdf = '/home/pedro/babystuff/forAgro/product list.pdf'
print('Opening pdf ... ')
with open(path2pdf, "rb") as attachment:
    filedata = attachment.read()
names = path2pdf.split('/')
fname = names[-1]
receiver_emails = ["[email protected]", "[email protected]", "[email protected]"] 
 
def send_email(attach, filename, sender, password, receiver, subject, body, server):    
    message = MIMEMultipart()
    # attach the file
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attach)
    encoders.encode_base64(part)
    part.add_header("Content-Disposition", f"attachment; filename= {filename}",)
    message["From"] = sender
    message["To"] = receiver
    message["Date"] = formatdate(localtime=True)
    message["Subject"] = subject
    message["Bcc"] = receiver  # Recommended for mass emails
    # Add body to email
    message.attach(MIMEText(body, "html"))
    message.attach(part)
    text = message.as_string()
    context = ssl.create_default_context()
    server.sendmail(sender, receiver, text)
    return "OK"

# this worked on QQ smtp, gmail is more difficult, higher security I suppose
port = 465  # or 587 For SL
smtp_server = "smtp.qq.com"
#smtp_server = "smtp.mail.yahoo.com"
context = ssl.create_default_context()
server = smtplib.SMTP_SSL(smtp_server, port, context=context)
# gmail or other mail servers may require the sender and login encoded base64
# in Linux do that in a bash terminal (command line) like this (don't know how in Windows):
# echo -ne "[email protected]" | base64
# which will return something like this:
# cGV0ZXJuYW5qaWdtYWlsLmNvb
# if necessary set sender and password, using your values:
# sender_email = "cGV0ZXJuYW5qaWdtYWlsLmNvb", password = "Z3JoYWF3c3J6cWh0"
# same for your app- password: echo -ne "abcdefghijklmnop" | base64
# QQ smtp server on port 465 works with the email address and IMAP password unencrypted
server.login(sender_email, password)
count = 1
for e in receiver_emails:
    print(f'Sending email {count} to {e} ... ')
    send_email(filedata, fname, sender_email, password, e, subject, html, server)
    print(f'Email {count} sent to {e} ... ')
    count +=1
server.quit()
print('All done!')
QQ mail stopped after about 200 emails sent. Girlfriend was not happy, she was doing this for work!

I think they would like you to pay for sending mass emails!
Reply
#3
Hi

Sorry to return so late.

I ran several tests and I came to the conclusion that the issue comes from the name of my files, something like

2025_07_01-2025_07_31 [RM] {Perlacremaz} Quittance N°122 (123 €).pdf

The message I send is seen as having 3 attachments, all of them named "default'

I have not been able to find out the contrains which apply on the names of the files.

Arbiel
using Ubuntu 22.04.5 LTS, Python 3.10.12
having substituted «https://www.lilo.org/fr/» to google, «https://protonmail.com/» to any other unsafe mail service and bépo to azerty (french keyboard layouts)
Reply
#4
Quote:I have not been able to find out the contrains which apply on the names of the files.
constraints??

Spaces in the names of the files perhaps?

This little bash script can remove all spaces from all file names in a folder:

Quote:echo "Script to replace all spaces in file names with _."
echo "Enter the absolute path to the files .... "
read path2files
echo "The directory to work on is $path2files"
cd $path2files
for file in *' '*; do
new_file="${file// /_}"
echo mv -n "$file" "$new_file"
done

Try this first. If no problems, remove echo to permanently change the file names
Reply
#5
pj0 work and pj1 fail because.
pj0 is plain ASCII plus spaces, so many mail clients will no tolerate your hand-built header.
pj1 has special characters ° € ,so a malformed or non-encoded header is much more likely to be ignored,
and the client may fall back to something like default.
Try instead.
import os
from email.mime.base import MIMEBase
from email import encoders

part = MIMEBase('application', 'pdf')

with open(pj1, "rb") as f:
    part.set_payload(f.read())

encoders.encode_base64(part)

part.add_header(
    'Content-Disposition',
    'attachment',
    filename=os.path.basename(pj1),
)

msg.attach(part)
A better modern approach is to use EmailMessage and add_attachment(),
which lets the stdlib build the MIME structure for you instead of manually composing MIMEBase parts.
from email.message import EmailMessage
import smtplib
import os

def smtp():
    msg = EmailMessage()
    msg["Subject"] = ""
    msg["From"] = ""
    msg["To"] = ""
    msg.set_content(gbl.objets['texte_message'])

    pj1 = '/home/arbiel/Téléchargements/Quittance N°132 (123 €).pdf'

    with open(pj1, "rb") as f:
        msg.add_attachment(
            f.read(),
            maintype="application",
            subtype="pdf",
            filename=os.path.basename(pj1),
        )

    with smtplib.SMTP('outgoing_server', 'outgoing_port') as mailServer:
        mailServer.login('sender_email', 'send_password')
        mailServer.send_message(msg)
Reply
#6
Hi snippsat

Thank you very much. It works fine. The name of the attachment is correctly inserted in tfe message.

Arbiel
using Ubuntu 22.04.5 LTS, Python 3.10.12
having substituted «https://www.lilo.org/fr/» to google, «https://protonmail.com/» to any other unsafe mail service and bépo to azerty (french keyboard layouts)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  smtplib send email has no timestamp Pedroski55 2 3,011 Jun-11-2024, 04:57 AM
Last Post: Pedroski55
  Unable to download TLS Report attachment blason16 6 2,708 Feb-26-2024, 07:36 AM
Last Post: Pedroski55
  Extract PDF Attachment from Gmail jstaffon 0 2,606 Sep-10-2023, 01:55 PM
Last Post: jstaffon
Sad What did I do wrongly? Tomi 1 1,962 Aug-07-2022, 08:05 AM
Last Post: Gribouillis
  I get attachment paperclip on email without any attachments monika_v 5 4,488 Mar-19-2022, 10:20 PM
Last Post: cosmarchy
  Trying to determine attachment file type before saving off.. cubangt 1 4,587 Feb-23-2022, 07:45 PM
Last Post: cubangt
  Sending Attachments via smtplib [SOLVED] AlphaInc 3 13,087 Oct-28-2021, 12:39 PM
Last Post: AlphaInc
  Sending random images via smtplib [SOLVED] AlphaInc 0 2,876 Oct-19-2021, 10:10 AM
Last Post: AlphaInc
  [UnicodeEncodeError from smtplib] yoohooos 0 5,368 Sep-25-2021, 04:27 AM
Last Post: yoohooos
  Clicking Every Page and Attachment on Website shoulddt 1 2,717 Jul-09-2021, 01:08 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020