Skip to content

Commit ca29f64

Browse files
committed
descriptions
1 parent 0aac3a1 commit ca29f64

File tree

1 file changed

+86
-54
lines changed

1 file changed

+86
-54
lines changed

source/integrations/flask-celery-integration.txt

Lines changed: 86 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
.. original URL: https://www.mongodb.com/developer/products/mongodb/python-flask-celery-newsletter/
33

44
======================================
5-
Tutorial: Celery and Flask Integration
5+
Tutorial: Flask and Celery Integration
66
======================================
77

88
.. contents:: On this page
@@ -21,38 +21,29 @@ Tutorial: Celery and Flask Integration
2121
Overview
2222
--------
2323

24-
In this tutorial, you can learn how to use MongoDB, Celery, and Flask
25-
to build a newsletter platform. This application allows users to subscribe to
26-
newsletters, and administrators to manage and send batch emails asynchronously.
27-
28-
Celery
29-
~~~~~~
30-
31-
Celery is an open-source distributed task queue that handles large
32-
volumes of messages efficiently. It supports asynchronous processing and task
33-
scheduling. For more information, see the `Celery webpage
34-
<https://docs.celeryq.dev/en/main/index.html>`__.
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.
3525

3626
Flask
3727
~~~~~
3828

3929
Flask is a lightweight web application framework with built-in configuration and
4030
convention defaults that provide consistency to developers across projects. For
41-
more information, see the `Flask webpage
42-
<https://flask.palletsprojects.com/en/stable/>`__.
31+
more information, see the `Flask webpage <https://flask.palletsprojects.com/en/stable/>`__.
32+
33+
Celery
34+
~~~~~~
35+
36+
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>`__.
4337

4438
Tutorial
4539
--------
4640

47-
This tutorial creates a modified version of the sample application in the
48-
:github:`Newsletter Platform with JavaScript, Flask, and MongoDB sample project
49-
</mercybassey/newsletter-javascript-flask-mongodb>` GitHub repository.
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.
5042

5143
Prerequisites
5244
~~~~~~~~~~~~~
5345

54-
Ensure that you have the following components installed and set up before you start
55-
this tutorial:
46+
Ensure that you have the following components installed and set up before you start this tutorial:
5647

5748
- A MongoDB cluster. We recommend that you use Atlas. To learn how
5849
to create an Atlas cluster, see the
@@ -65,7 +56,7 @@ this tutorial:
6556
- `Gmail <www.gmail.com>`__ to use as an SMTP server. For more information about
6657
SMTP servers, see the :wikipedia:`Simple Mail Transfer Protocol
6758
<Simple_Mail_Transfer_Protocol>` Wikipedia page.
68-
- `Python 3.8 or later <https://www.python.org/downloads/>`__
59+
- `Python 3.9 or later <https://www.python.org/downloads/>`__
6960

7061
Setup
7162
~~~~~
@@ -130,20 +121,18 @@ Setup
130121

131122
.. code-block:: bash
132123

133-
pip install Flask Flask-Mail pymongo celery
124+
pip install flask-pymongo Flask-Mail celery
134125

135126
Configure Your Application
136127
~~~~~~~~~~~~~~~~~~~~~~~~~~
137128

138-
The ``config.py`` file contains the settings and credentials to perform the
139-
following actions:
129+
The ``config.py`` file contains the settings and credentials to perform the following actions:
140130

141131
- Connect Celery to RabbitMQ as its message broker
142132
- Configure Flask-Mail to use Gmail as its SMTP server
143133
- Connect your application to your MongoDB server
144134

145-
Define the necessary configurations by adding the following code to your
146-
``config.py`` file:
135+
Define the necessary configurations by adding the following code to your ``config.py`` file:
147136

148137
.. code-block:: python
149138

@@ -160,25 +149,22 @@ Define the necessary configurations by adding the following code to your
160149
CELERY_BROKER_URL = 'amqp://guest:guest@localhost//'
161150
RESULT_BACKEND = MONGO_URI + '/celery_results'
162151

163-
You must provide your Gmail credentials (``MAIL_USERNAME`` and ``MAIL_PASSWORD``) to
164-
enable your application to send emails. For security purposes, we recommend that
165-
you generate an app password to use, rather than using your primary password.
166-
For more information, see the `App Password settings
167-
<https://myaccount.google.com/apppasswords>`__ in your Google Account.
152+
You must provide your Gmail credentials (``MAIL_USERNAME`` and ``MAIL_PASSWORD``) 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.
168153

169-
You must also create a connection string to set into the ``MONGO_URI``
170-
environment variable. For more information see the :ref:`Create a Connection
171-
String <pymongo-get-started-connection-string>` section of this guide.
154+
You must also create 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.
172155

173-
The provided Celery broker URL (``CELERY_BROKER_URL``) specifies RabbitMQ as its broker,
174-
but you can customize this URL to support other implementations. For more
175-
information, see the `Broker Settings
176-
<https://docs.celeryq.dev/en/stable/userguide/configuration.html#broker-settings>`__
177-
section of the Celery documentation.
156+
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.
178157

179158
Initialize Flask, MongoDB, and Celery
180159
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181160

161+
The ``app.py`` file initializes and configures the core components of the Flask application. It performs the following tasks:
162+
163+
- Creates a Flask application and loads configuration constants
164+
- Initializes a Flask-Mail instance with the app's mail server settings
165+
- Connects to the ``newsletter`` MongoDB database by using the {+driver-short+} driver
166+
- Creates a Celery instance configured with the Flask app and your chosen broker
167+
182168
Initialize Flask, MongoDB, and Celery by adding the following code to your
183169
``app.py`` file:
184170

@@ -189,13 +175,18 @@ Initialize Flask, MongoDB, and Celery by adding the following code to your
189175
from pymongo import MongoClient
190176
from celery import Celery
191177

178+
# Create a Flask application
192179
app = Flask(__name__)
193180
app.config.from_object('config.Config')
194181

182+
# Create a Flask-Mail instance
195183
mail = Mail(app)
184+
185+
# Connect to MongoDB
196186
client = MongoClient(app.config['MONGO_URI'])
197187
db = client.get_database(name="newsletter")
198188

189+
# Create a Celery instance
199190
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
200191
celery.conf.update(app.config)
201192

@@ -205,13 +196,58 @@ Initialize Flask, MongoDB, and Celery by adding the following code to your
205196
if __name__ == '__main__':
206197
app.run(debug=True)
207198

208-
This opens a connection to the ``newsletter`` database in your MongoDB cluster
209-
and configures your Celery task queue.
199+
Create a Celery Task
200+
~~~~~~~~~~~~~~~~~~~~
201+
202+
The Celery task uses the components instantiated in your ``app.py`` file to send a newsletter email to subscribers.
203+
204+
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.
205+
206+
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.
207+
208+
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.
209+
210+
Define your ``send_emails()`` method by adding the following code to your ``tasks.py`` file:
211+
212+
.. code-block:: python
213+
214+
from flask_mail import Message
215+
from app import app, mail, db, celery
216+
from datetime import datetime
217+
218+
@celery.task(bind=True)
219+
def send_emails(self, subscribers, title, body):
220+
with app.app_context():
221+
for subscriber in subscribers:
222+
try:
223+
print(f"Sending email to {subscriber['email']}")
224+
msg = Message(title, recipients=[subscriber['email']])
225+
msg.body = body
226+
mail.send(msg)
227+
db.deliveries.insert_one({
228+
'email': subscriber['email'],
229+
'title': title,
230+
'body': body,
231+
'delivered_at': datetime.utcnow()
232+
})
233+
print("Email sent")
234+
235+
except Exception as e:
236+
print(f"Failed to send email to {subscriber['email']}: {str(e)}")
237+
238+
return {'result': 'All emails sent'}
239+
210240

211241
Define Your Routes
212242
~~~~~~~~~~~~~~~~~~
213243

214-
Define the ``root``, ``admin``, ``subscribe``, and ``send-newsletter`` routes by adding the following code to your ``routes.py`` file:
244+
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-newsletter`` routes. The optional ``methods`` parameter is used in some cases to define a list of allowable HTTP methods.
245+
246+
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``.
247+
248+
The root and ``/admin`` routes render pages using the ``render_template()`` method. The ``/subscribe`` and ``/send-newsletter`` routes access request parameters in ``request.form[]`` to execute commands, and then return HTTP responses.
249+
250+
Define your routes by adding the following code to your ``routes.py`` file:
215251

216252
.. code-block:: python
217253

@@ -275,14 +311,12 @@ application in this file.
275311
Create Your Pages
276312
~~~~~~~~~~~~~~~~~
277313

278-
You can build your user interface in the ``templates`` directory.
314+
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.
279315

280-
Because this application uses asynchronous messages, the scripts in the
281-
following files use :wikipedia:`Fetch API calls <XMLHttpRequest#Fetch_alternative>`. They also
282-
handle timeouts and errors.
316+
Subscribe Pages
317+
```````````````
283318

284-
Copy the following code into your ``subscribe.html`` file to create your
285-
:guilabel:`Subscribe to Newsletter` page.
319+
Copy the following code into your ``subscribe.html`` file to create your :guilabel:`Subscribe to Newsletter` page.
286320

287321
.. code-block:: html
288322

@@ -340,6 +374,9 @@ Copy the following code into your ``subscribe.html`` file to create your
340374
</body>
341375
</html>
342376

377+
Admin Page
378+
```````````
379+
343380
The script for the admin page displays an alert to the user that depends on the
344381
success of the ``send_newsletter`` call.
345382

@@ -399,8 +436,7 @@ Copy the following code into your ``admin.html`` file to create your
399436
Format Your Pages
400437
~~~~~~~~~~~~~~~~~
401438

402-
You can apply a style sheet to your templates by adding the following code to
403-
the ``styles.css`` file:
439+
You can apply a style sheet to your templates by adding the following code to the ``styles.css`` file:
404440

405441
.. code-block:: css
406442

@@ -480,14 +516,10 @@ the ``styles.css`` file:
480516
color: #666;
481517
}
482518

483-
You can modify this style sheet or create your own to customize your
484-
application.
485-
486519
Testing the Platform
487520
~~~~~~~~~~~~~~~~~~~~
488521

489-
After you complete the previous steps, you have a working application that
490-
uses MongoDB, Flask, and Celery to manage a newsletter platform.
522+
After you complete the previous steps, you have a working application that uses MongoDB, Flask, and Celery to manage a newsletter platform.
491523

492524
You can use the following steps to test your application:
493525

0 commit comments

Comments
 (0)