1. Paul McLanahan
  2. django-celery-email
  3. Pull requests

Pull requests

#2 Merged

Save backend constructor kwargs in the init_kwargs and use them in the task when calling get_connection

  1. Fedor Tyurin

This fixes the issue, which i've reported.

Comments (6)

  1. Paul McLanahan repo owner

    This looks interesting. I didn't realize that it was common to use the constructor args of the SMTP backend to setup auth. This will need some tests to ensure that the args really are making it to the SMTP backend. Add some and I'll get it merged and released.

    Thanks for the contribution!

    1. Fedor Tyurin author

      It's very good that you asked me to write tests :) Now I realized that there is a bug in my code caused by the inconsistent behavior of django core mail functionality (you must have received notification about the issue https://code.djangoproject.com/ticket/17811, which i created in django trac system). There are two possible workarounds for this. The first one would be to add extra parameter to the task function to pass init_kwargs (keyword arguments passed to the original backend constructor). And the second one would be to put init_kwargs into the message object just before passing it to the task function. The second one is dirty in my opinion, but doesn't require changes in the interface of the task. The third option would be just to replace **message.connection.init_kwargs with **getattrs(message.connection, 'init_kwargs', {}), which means that celery email backend will correctly work only when connection is set in the message. Please share your opinion.

      1. Paul McLanahan repo owner

        I like what you've done, but I think I like your first option best. Since the task already accepts **kwargs, we could just do something like:

            def send_messages(self, email_messages, **kwargs):
                results = []
                kwargs['backend_kwargs'] = self.init_kwargs
                for msg in email_messages:
                    results.append(send_email.delay(msg, **kwargs))
                return results

        then in the task:

            conn = get_connection(backend=BACKEND, **kwargs.get('backend_kwargs', {}))

        I think that's the most strait-forward, readable, and reliable.

        Thanks for the options, and for CCing me on the django bug.