Attachments

.attach(source, filename=None, mimetype=None), callable as many times as you like, order preserved. Attachments ride the same message and are identical across language groups. Nothing is read until .send().

from pathlib import Path

Email("imio.pm.notifications:meeting_convocation").to(members).attach(
    convocation
).attach(Path("/srv/exports/annexe.pdf")).attach(
    pdf_bytes, filename="rapport.pdf", mimetype="application/pdf"
).send()

convocation there is a Plone File object, which carries its own filename and content type; the path carries a filename and a guessable type; the raw bytes carry neither, which is why both are passed.

Accepted sources

  • Name
    bytes
    Description

    Carries nothing but the data, so both filename and mimetype are required.

  • Name
    A filesystem path
    Type
    str or pathlib.Path
    Description

    filename comes from the path; mimetype is guessed from it via mimetypes.guess_type.

  • Name
    An open binary file object
    Description

    Anything with .read(). A name attribute, if present, supplies the filename.

  • Name
    A blob value
    Type
    NamedFile, NamedBlobFile
    Description

    Carries both its own filename and its own contentType.

  • Name
    A Plone content object
    Type
    File, Image
    Description

    Resolved through its primary field, so it carries both too.

Metadata precedence

For both filename and mimetype: what you passed wins, then what the source carries, then — for the mimetype only — what mimetypes.guess_type makes of the filename.

An explicit argument overriding a blob's own contentType is the point of having the arguments at all: a stored application/octet-stream should not be what a recipient's mail client sees.

When it fails

AttachmentError at .send(), for an unreadable source or for a filename / mimetype that could not be inferred and was not passed. Like RecipientError, it reports every problem it found rather than the first one.

Nothing is silently skipped. A mail that arrives without the convocation it was sent to deliver is the failure mode this exception exists to make impossible.

Not in this version

Inline cid: images. The theme logo and any imagery are remote URLs. .attach(..., inline=True) with cid generation is the natural extension point if a client environment ever blocks remote images as policy.