Sometimes, you want your web app to do long jobs without making users wait. Calling tasks asynchronously lets your app start a job and keep working without delay.
Calling tasks asynchronously in Flask
from flask import Flask from flask_mail import Mail, Message from threading import Thread app = Flask(__name__) mail = Mail(app) def send_async_email(app, msg): with app.app_context(): mail.send(msg) @app.route('/send-email') def send_email(): msg = Message('Hello', sender='you@example.com', recipients=['friend@example.com']) msg.body = 'This is an async email.' thread = Thread(target=send_async_email, args=(app, msg)) thread.start() return 'Email is being sent!'
Use a separate thread or a task queue to run tasks without blocking the main app.
Make sure to pass the app context if your task needs Flask features.
from threading import Thread def background_task(): print('Task running') thread = Thread(target=background_task) thread.start()
from flask import Flask from flask_mail import Mail, Message from threading import Thread app = Flask(__name__) mail = Mail(app) def send_async_email(app, msg): with app.app_context(): mail.send(msg) @app.route('/send-email') def send_email(): msg = Message('Hi', sender='you@example.com', recipients=['friend@example.com']) msg.body = 'Async email body' Thread(target=send_async_email, args=(app, msg)).start() return 'Email sent asynchronously!'
This Flask app starts a long task in the background when you visit the home page. The page responds immediately while the task runs.
from flask import Flask from threading import Thread import time app = Flask(__name__) def long_task(): print('Task started') time.sleep(5) # Simulate a long job print('Task finished') @app.route('/') def index(): thread = Thread(target=long_task) thread.start() return 'Long task started, you can keep browsing!' if __name__ == '__main__': app.run(debug=True)
Using threads is simple but not always best for heavy tasks; consider task queues like Celery for bigger apps.
Always be careful with shared data when using threads to avoid conflicts.
Asynchronous tasks let your app do long jobs without making users wait.
Use threads or task queues to run tasks in the background.
Remember to handle Flask app context when running tasks outside the main thread.
Practice
Solution
Step 1: Understand asynchronous task purpose
Asynchronous tasks let the app do long jobs in the background.Step 2: Connect to user experience
This means users don't have to wait for the task to finish before using the app.Final Answer:
It allows the app to handle long tasks without making users wait. -> Option DQuick Check:
Async tasks improve user wait time = C [OK]
- Thinking async tasks slow down the app
- Believing users must refresh manually
- Assuming async disables other app parts
Solution
Step 1: Recall Python threading syntax
To start a thread, create Thread with target function, then call start().Step 2: Match options to syntax
threading.Thread(target=task).start() matches correct syntax: threading.Thread(target=task).start()Final Answer:
threading.Thread(target=task).start() -> Option CQuick Check:
Correct thread start syntax = A [OK]
- Calling start() on the function instead of the thread
- Using undefined functions like start_thread
- Confusing run() with start() method
from threading import Thread
from flask import Flask
app = Flask(__name__)
def background_task():
print('Task done')
@app.route('/')
def index():
Thread(target=background_task).start()
return 'Hello'Solution
Step 1: Understand thread behavior in Flask route
The route starts a thread to run background_task, then returns 'Hello' immediately.Step 2: Predict output order
'Hello' is sent to user right away; 'Task done' prints later when thread runs.Final Answer:
Hello printed immediately, then 'Task done' printed later -> Option AQuick Check:
Thread runs task after response = A [OK]
- Thinking 'Task done' prints before 'Hello'
- Assuming thread blocks response
- Believing thread syntax is wrong here
from threading import Thread
from flask import Flask
app = Flask(__name__)
def task():
print(app.name)
@app.route('/')
def index():
Thread(target=task).start()
return 'Done'Solution
Step 1: Identify Flask app context issue
Background threads don't have Flask app context by default, so accessing app.name can fail.Step 2: Understand context handling
To fix, use app.app_context() inside the thread to provide context.Final Answer:
The background thread lacks Flask app context, causing errors. -> Option BQuick Check:
Missing app context in thread = D [OK]
- Calling target function instead of passing it
- Thinking Flask disallows printing app.name
- Believing route must return JSON always
Solution
Step 1: Recall Flask app context rules
Background tasks need explicit app context to access Flask features like database.Step 2: Identify correct context usage
Usingwith app.app_context():inside the task ensures context is active during task execution.Step 3: Eliminate incorrect options
Calling task directly blocks request; Flask does not share context automatically; app.run() starts server, not context.Final Answer:
Usewith app.app_context():inside the background task function. -> Option AQuick Check:
Use app.app_context() in thread = B [OK]
- Running task directly blocking the app
- Assuming Flask shares context automatically
- Misusing app.run() inside tasks
Ready to prove it?
Pass the test and this pattern moves unknown
