Reputation: 18735
I'm trying to figure out how to send email asynchroniously so User
don't have to wait until email
is sent.
I've installer celery
and django-celery-email
and added django-celery-email
into my settings.py
- djcelery_email
.
I've also changed database backend:
EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'
Now I've tried to do an action which sends email but it freezes and no email has been sent.
Do you know what to do?
Here is a traceback from cmd:
Internal Server Error: /ajax/reservation/confirm/
Traceback (most recent call last):
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\views.py", line 68, in reservation_confirm
reservation.save()
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\models.py", line 150, in save
notifications.AdminNotifications.new_pair(self, paired_reservation)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\notifications.py", line 79, in new_pair
send_message_to_admin(subject,message)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\notifications.py", line 8, in send_message_to_admin
mail.send()
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\mail\message.py", line 292, in send
return self.get_connection(fail_silently).send_messages([self])
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\djcelery_email\backends.py", line 17, in send_messages
result_tasks.append(send_emails.delay(chunk, self.init_kwargs))
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\task.py", line 453, in delay
return self.apply_async(args, kwargs)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\task.py", line 565, in apply_async
**dict(self._get_exec_options(), **options)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\base.py", line 354, in send_task
reply_to=reply_to or self.oid, **options
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\amqp.py", line 310, in publish_task
**kwargs
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\messaging.py", line 172, in publish
routing_key, mandatory, immediate, exchange, declare)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 457, in _ensured
interval_max)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 369, in ensure_connection
interval_start, interval_step, interval_max, callback)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\utils\__init__.py", line 246, in retry_over_time
return fun(*args, **kwargs)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 237, in connect
return self.connection
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 742, in connection
self._connection = self._establish_connection()
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 697, in _establish_connection
conn = self.transport.establish_connection()
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\transport\pyamqp.py", line 116, in establish_connection
conn = self.Connection(**opts)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\connection.py", line 165, in __init__
self.transport = self.Transport(host, connect_timeout, ssl)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\connection.py", line 186, in Transport
return create_transport(host, connect_timeout, ssl)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\transport.py", line 299, in create_transport
return TCPTransport(host, connect_timeout)
File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\transport.py", line 95, in __init__
raise socket.error(last_err)
error: [Errno 10061] No connection could be made because the target machine actively refused it
Upvotes: 0
Views: 1105
Reputation: 12255
From https://github.com/pmclanahan/django-celery-email
By default django-celery-email will use Django's builtin SMTP email backend for the actual sending of the mail.
This means you need to run an SMTP server locally to accept the email. That is why you are getting a socket error - cause you don't have any SMTP server set to receive the email.
Option 1
Run a combined SMTP server and client. Mailcatcher is great for this.
It even comes with django setup instructions!
Set it up then fire it up with:
$ mailcatcher -fv
Note: mailcatcher requires gem (ruby package manager) to install. So you will have to install that first. Its probably worth the effort, as mailcatcher works quite nicely and gives you html and text representations of the email in a browser tab.
For docker users you can get a mailcatcher docker image
Option 2
Run your own SMTP server and a separate mail client.
e.g. Use a simple python SMTP server
From the command line
python -m smtpd -n -c DebuggingServer localhost:1025
in your django settings:
EMAIL_HOST = 'localhost'
EMAIL_HOST_USER = None
EMAIL_HOST_PASSWORD = None
EMAIL_PORT = 1025
EMAIL_USE_TLS = False
Then you will need to setup a client to get those emails.
Instead print to the console:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Problem with this is ugly formatting. HTML will appear as text which makes the email very hard to read. You can output this to a file by manually copying and pasting it into a .html file and opening it in a browser, but that will get boring very fast.
Use this for making email accessible to the django test client, so you can check that emails got sent, check the content of email programatically etc.
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
You will need to use a SMTP server again. Either you can run your own or use Sendgrid, Mailgun, Mandrill or something similar.
Upvotes: 1