You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -21,29 +21,38 @@ Tutorial: Flask and Celery Integration
21
21
Overview
22
22
--------
23
23
24
-
In this tutorial, you can learn how to use MongoDB, Flask, and Celery to build a newsletter platform. This application allows users to subscribe to newsletters, and administrators to manage and send batch emails asynchronously.
24
+
In this tutorial, you can learn how to use MongoDB, Flask, and Celery to build a
25
+
newsletter platform. This application allows users to subscribe to newsletters,
26
+
and administrators to manage and send batch emails asynchronously.
25
27
26
28
Flask
27
29
~~~~~
28
30
29
31
Flask is a lightweight web application framework with built-in configuration and
30
32
convention defaults that provide consistency to developers across projects. For
31
-
more information, see the `Flask webpage <https://flask.palletsprojects.com/en/stable/>`__.
Celery is an open-source distributed task queue that handles large volumes of messages efficiently. It supports asynchronous processing and task scheduling. For more information, see the `Celery webpage <https://docs.celeryq.dev/en/main/index.html>`__.
39
+
Celery is an open-source distributed task queue that handles large volumes of
40
+
messages efficiently. It supports asynchronous processing and task scheduling.
41
+
For more information, see the `Celery webpage
42
+
<https://docs.celeryq.dev/en/main/index.html>`__.
37
43
38
44
Tutorial
39
45
--------
40
46
41
-
This tutorial creates a modified version of the sample application in the :github:`Newsletter Platform with JavaScript, Flask, and MongoDB sample project </mercybassey/newsletter-javascript-flask-mongodb>` GitHub repository.
47
+
This tutorial creates a modified version of the sample application in the
48
+
:github:`Newsletter Platform with JavaScript, Flask, and MongoDB sample project
You must provide your Gmail credentials and email (``MAIL_USERNAME``, ``MAIL_PASSWORD``, and ``MAIL_DEFAULT_SENDER``) to enable your application to send emails. For security purposes, we recommend that you generate an app password to use, rather than using your primary password. For more information, see the `App Password settings <https://myaccount.google.com/apppasswords>`__ in your Google Account.
171
+
You must provide your Gmail credentials and email (``MAIL_USERNAME``,
172
+
``MAIL_PASSWORD``, and ``MAIL_DEFAULT_SENDER``) to enable your application to
173
+
send emails. For security purposes, we recommend that you generate an app
174
+
password to use, rather than using your primary password. For more information,
175
+
see the `App Password settings <https://myaccount.google.com/apppasswords>`__ in
176
+
your Google Account.
154
177
155
-
You must also provide a connection string to set into the ``MONGO_URI`` environment variable. For more information see the :ref:`Create a Connection String <pymongo-get-started-connection-string>` section of this guide.
178
+
You must also provide a connection string to set into the ``MONGO_URI``
179
+
environment variable. For more information see the :ref:`Create a Connection
180
+
String <pymongo-get-started-connection-string>` section of this guide.
156
181
157
-
The provided Celery broker URL (``CELERY_BROKER_URL``) specifies RabbitMQ as its broker, but you can customize this URL to support other implementations. For more information, see the `Broker Settings <https://docs.celeryq.dev/en/stable/userguide/configuration.html#broker-settings>`__ section of the Celery documentation.
182
+
The provided Celery broker URL (``CELERY_BROKER_URL``) specifies RabbitMQ as its
183
+
broker, but you can customize this URL to support other implementations. For
The ``ALLOWED_IPS`` list is used to control access to the :guilabel:`Send Newsletter` page. The rest of the variables configure the Flask and Celery components.
188
+
The ``ALLOWED_IPS`` list is used to control access to the :guilabel:`Send
189
+
Newsletter` page. The rest of the variables configure the Flask and Celery
190
+
components.
160
191
161
192
Initialize Flask, MongoDB, and Celery
162
193
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163
194
164
-
The ``app.py`` file initializes and configures the core components of the Flask application. It performs the following tasks:
195
+
The ``app.py`` file initializes and configures the core components of the Flask
196
+
application. It performs the following tasks:
165
197
166
198
- Creates a Flask application and loads configuration constants
167
199
- Initializes a Flask-Mail instance with the app's mail server settings
168
-
- Connects to the ``newsletter`` MongoDB database by using the {+driver-short+} driver
200
+
- Connects to the ``newsletter`` MongoDB database by using the {+driver-short+}
201
+
driver
169
202
- Creates a Celery instance configured with the Flask app and your chosen broker
170
203
171
204
Initialize Flask, MongoDB, and Celery by adding the following code to your
@@ -202,15 +235,32 @@ Initialize Flask, MongoDB, and Celery by adding the following code to your
202
235
Create a Celery Task
203
236
~~~~~~~~~~~~~~~~~~~~
204
237
205
-
The Celery task uses the components instantiated in your ``app.py`` file to send a newsletter email to subscribers.
206
-
207
-
The ``@celery.task()`` decorator registers the function as a Celery task. Setting ``bind=True`` means the function receives the task instance as the ``self`` argument, which allows it to access Celery task methods and metadata. For more information about tasks, see the `celery.app.task <https://docs.celeryq.dev/en/stable/reference/celery.app.task.html>`__ API documentation.
208
-
209
-
Since this task runs outside of Flask's HTTP request cycle, you must manually provide application context by wrapping the email logic in a ``with app.app_context()`` block. This gives Flask access to other components like the Flask-Mail ``mail`` instance and the {+driver-short+} connection to your ``newsletter`` MongoDB database.
210
-
211
-
This method loops through the list of ``subscribers``, creates an email using the Flask-Mail ``Message`` class, and then sends it to each user by using the ``mail`` object. After each email is sent, it logs the delivery by inserting a document into your MongoDB ``deliveries`` collection to record that the message was sent. Each email operation is wrapped in a ``try`` block to ensure that in the case of an error, the failure is logged and the database is not updated with a false delivery record.
212
-
213
-
Define your ``send_emails()`` method by adding the following code to your ``tasks.py`` file:
238
+
The Celery task uses the components instantiated in your ``app.py`` file to send
239
+
a newsletter email to subscribers.
240
+
241
+
The ``@celery.task()`` decorator registers the function as a Celery task.
242
+
Setting ``bind=True`` means the function receives the task instance as the
243
+
``self`` argument, which allows it to access Celery task methods and metadata.
244
+
For more information about tasks, see the `celery.app.task
245
+
<https://docs.celeryq.dev/en/stable/reference/celery.app.task.html>`__ API
246
+
documentation.
247
+
248
+
Since this task runs outside of Flask's HTTP request cycle, you must manually
249
+
provide application context by wrapping the email logic in a ``with
250
+
app.app_context()`` block. This gives Flask access to other components like the
251
+
Flask-Mail ``mail`` instance and the {+driver-short+} connection to your
252
+
``newsletter`` MongoDB database.
253
+
254
+
This method loops through the list of ``subscribers``, creates an email using
255
+
the Flask-Mail ``Message`` class, and then sends it to each user by using the
256
+
``mail`` object. After each email is sent, it logs the delivery by inserting a
257
+
document into your MongoDB ``deliveries`` collection to record that the message
258
+
was sent. Each email operation is wrapped in a ``try`` block to ensure that in
259
+
the case of an error, the failure is logged and the database is not updated with
260
+
a false delivery record.
261
+
262
+
Define your ``send_emails()`` method by adding the following code to your
263
+
``tasks.py`` file:
214
264
215
265
.. code-block:: python
216
266
@@ -236,19 +286,30 @@ Define your ``send_emails()`` method by adding the following code to your ``task
236
286
print("Email sent")
237
287
238
288
except Exception as e:
239
-
print(f"Failed to send email to {subscriber['email']}: {str(e)}")
289
+
print(f"Failed to send email to {subscriber['email']}: {str(e)}")
240
290
241
291
return {'result': 'All emails sent'}
242
292
243
293
244
294
Define Your Routes
245
295
~~~~~~~~~~~~~~~~~~
246
296
247
-
In Flask, the ``@app.route()`` decorator assigns a URL path to a specific function. In the following code, it is used to define the root (``/``), ``/admin``, ``/subscribe``, and ``/send-newsletters`` routes. The optional ``methods`` parameter is used in some cases to define a list of allowable HTTP methods.
297
+
In Flask, the ``@app.route()`` decorator assigns a URL path to a specific
298
+
function. In the following code, it is used to define the root (``/``),
299
+
``/admin``, ``/subscribe``, and ``/send-newsletters`` routes. The optional
300
+
``methods`` parameter is used in some cases to define a list of allowable HTTP
301
+
methods.
248
302
249
-
The ``@app.before_request()`` method sets a function to run before every request. In this case, the function provides some basic security by limiting access to the ``admin`` page to IP addresses listed in the ``ALLOWED_IPS`` parameter defined in the ``config.py`` file. Specifically, access is only allowed for the ``localhost``.
303
+
The ``@app.before_request()`` method sets a function to run before every
304
+
request. In this case, the function provides some basic security by limiting
305
+
access to the ``admin`` page to IP addresses listed in the ``ALLOWED_IPS``
306
+
parameter defined in the ``config.py`` file. Specifically, access is only
307
+
allowed for the ``localhost``.
250
308
251
-
The root and ``/admin`` routes render pages using the ``render_template()`` method. The ``/subscribe`` and ``/send-newsletters`` routes access request parameters in ``request.form[]`` to execute commands, and then return HTTP responses.
309
+
The root and ``/admin`` routes render pages using the ``render_template()``
310
+
method. The ``/subscribe`` and ``/send-newsletters`` routes access request
311
+
parameters in ``request.form[]`` to execute commands, and then return HTTP
312
+
responses.
252
313
253
314
Define your routes by adding the following code to your ``routes.py`` file:
254
315
@@ -314,12 +375,17 @@ application in this file.
314
375
Create Your Pages
315
376
~~~~~~~~~~~~~~~~~
316
377
317
-
The HTML files in the ``templates`` directory define the user interface, and are written using standard HTML. Since this application uses asynchronous HTTP requests, the scripts in these files use :wikipedia:`Fetch API calls <XMLHttpRequest#Fetch_alternative>`. These scripts also handle timeouts and errors.
378
+
The HTML files in the ``templates`` directory define the user interface, and are
379
+
written using standard HTML. Since this application uses asynchronous HTTP
380
+
requests, the scripts in these files use :wikipedia:`Fetch API calls
381
+
<XMLHttpRequest#Fetch_alternative>`. These scripts also handle timeouts and
382
+
errors.
318
383
319
384
Subscribe Page
320
385
```````````````
321
386
322
-
Copy the following code into your ``subscribe.html`` file to create your :guilabel:`Subscribe to Newsletter` page.
387
+
Copy the following code into your ``subscribe.html`` file to create your
388
+
:guilabel:`Subscribe to Newsletter` page.
323
389
324
390
.. code-block:: html
325
391
@@ -439,7 +505,8 @@ Copy the following code into your ``admin.html`` file to create your
439
505
Format Your Pages
440
506
~~~~~~~~~~~~~~~~~
441
507
442
-
You can apply a style sheet to your templates by adding the following code to the ``styles.css`` file:
508
+
You can apply a style sheet to your templates by adding the following code to
509
+
the ``styles.css`` file:
443
510
444
511
.. code-block:: css
445
512
@@ -522,7 +589,8 @@ You can apply a style sheet to your templates by adding the following code to th
522
589
Test the Application
523
590
~~~~~~~~~~~~~~~~~~~~
524
591
525
-
After you complete the previous steps, you have a working application that uses MongoDB, Flask, and Celery to manage a newsletter platform.
592
+
After you complete the previous steps, you have a working application that uses
593
+
MongoDB, Flask, and Celery to manage a newsletter platform.
526
594
527
595
You can use the following steps to test your application:
528
596
@@ -600,7 +668,10 @@ You can use the following steps to test your application:
600
668
Next Steps
601
669
~~~~~~~~~~
602
670
603
-
This application demonstrates how to integrate a Flask application with the Celery task queue to manage subscriber data, and send batch emails. You can further enhance this platform by integrating analytics, customizing email templates, and implementing automated responses.
671
+
This application demonstrates how to integrate a Flask application with the
672
+
Celery task queue to manage subscriber data, and send batch emails. You can
673
+
further enhance this platform by integrating analytics, customizing email
674
+
templates, and implementing automated responses.
604
675
605
676
More Resources
606
677
--------------
@@ -612,4 +683,5 @@ For more information about the components used in this tutorial, see the followi
0 commit comments