Search code examples
pythondjangopython-importmutt

Have Django use Mutt as its email backend?


I know that you can use the EMAIL_BACKEND setting, and I think I have written a working mutt backend, but I can't set my EMAIL_BACKEND to my class because it apparently has to be the string import path, not the name of the class. The local path (emails) doesn't work because the current directory apparently isn't in the Python import path. And I can't use local package imports (from . import) because, of course, it has to be a simple string.

I got it working by copying my module into /usr/local/lib/python3.7/, but that's such a terrible long-term solution that it isn't even worth it.

My project directory structure is like: django/project/app/, with emails.py under app/, alongside settings.py and the others. The project/app structure didn't make a lot of sense to me (I only have one app) but I got the impression that it was the intended way to setup Django, so I did that.

It shouldn't be relevant, but BTW my mutt backend code is:

import subprocess
from django.core.mail.backends.base import BaseEmailBackend

class MuttBackend(BaseEmailBackend):
    def send_messages(self, email_messages):
        for m in email_messages: self.send(m)
    def send(self, message):
        print(message.subject, message.from_email, message.to, message.body)
        mutt = subprocess.Popen(args = ['/usr/local/bin/mutt', *message.to,
            '-s', message.subject,
            '-e', f'set from="{message.from_email}"'],
            stdin = subprocess.PIPE)
        mutt.stdin.write(bytes(message.body, 'utf-8'))
        mutt.stdin.close()

How can I set EMAIL_BACKEND to a class without using its import path, or find another workaround? I did some googling but couldn't find anyone else who had gotten anything like this to work.


Solution

  • I figured it out. The default config assumed uWSGI was running in project/, not project/app/, so the import path I needed was app.emails.MuttBackend.