🎪 The Magic Messenger: Flask User State & Feedback
Imagine you’re running a carnival booth. You need to remember who visited, leave them notes, and know what time zone they’re in. That’s exactly what Flask does with sessions, flash messages, and cookies!
🎯 What You’ll Learn
Think of your web app as a friendly shop assistant who:
- Remembers who you are (Sessions)
- Leaves sticky notes for you (Flash messages)
- Gives you a loyalty card (Cookies)
- Knows your local time (Timezone handling)
📝 Flash Messages: Sticky Notes for Your Users
What Are Flash Messages?
Imagine you walk into a store, buy something, and the cashier puts a sticky note on your bag saying “Thanks for shopping!” That’s a flash message!
Flash messages are one-time notes that:
- Show up ONCE
- Then disappear forever
- Perfect for “Success!” or “Oops, try again” messages
Simple Example
from flask import Flask, flash, redirect
from flask import render_template, url_for
app = Flask(__name__)
app.secret_key = 'super-secret'
@app.route('/buy')
def buy_item():
# Leave a sticky note!
flash('You bought it! 🎉')
return redirect(url_for('home'))
Reading Flash Messages in HTML
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for msg in messages %}
<div class="alert">{{ msg }}</div>
{% endfor %}
{% endif %}
{% endwith %}
🏷️ Message Categories: Colored Sticky Notes
Why Categories?
Not all messages are the same!
- ✅ Green for success
- ❌ Red for errors
- ⚠️ Yellow for warnings
- ℹ️ Blue for info
How to Use Categories
# Success message (green note)
flash('Saved!', 'success')
# Error message (red note)
flash('Oops! Try again.', 'error')
# Warning message (yellow note)
flash('Almost out of stock!', 'warning')
# Info message (blue note)
flash('New feature available!', 'info')
Reading Categories in HTML
{% with messages = get_flashed_messages(
with_categories=true) %}
{% for category, msg in messages %}
<div class="alert alert-{{ category }}">
{{ msg }}
</div>
{% endfor %}
{% endwith %}
🗃️ Sessions: Your App’s Memory
The Carnival Wristband Analogy
When you enter a carnival, you get a wristband. Every ride operator can see it and knows you paid. That’s a session!
Sessions remember things like:
- Is this user logged in?
- What’s in their shopping cart?
- What language do they prefer?
Basic Session Usage
from flask import session
# Store something
@app.route('/login')
def login():
session['user'] = 'Alice'
session['logged_in'] = True
return 'Welcome, Alice!'
# Read it back
@app.route('/profile')
def profile():
name = session.get('user', 'Guest')
return f'Hello, {name}!'
# Remove it
@app.route('/logout')
def logout():
session.pop('user', None)
session.clear() # Remove ALL
return 'Goodbye!'
graph TD A[User Visits] --> B{Session Exists?} B -->|No| C[Create New Session] B -->|Yes| D[Load Session Data] C --> E[Store in Cookie] D --> F[Use Data in App]
⚙️ Session Configuration: Setting the Rules
The Secret Key: Your Master Lock
# REQUIRED! Without this, sessions fail
app.secret_key = 'my-super-secret-key-123'
# Better: Use environment variable
import os
app.secret_key = os.environ.get(
'SECRET_KEY',
'fallback-dev-key'
)
Configuration Options
| Setting | What It Does | Example |
|---|---|---|
SECRET_KEY |
Encrypts session | Required! |
SESSION_COOKIE_NAME |
Cookie name | 'my_session' |
PERMANENT_SESSION_LIFETIME |
How long | timedelta(days=7) |
SESSION_COOKIE_SECURE |
HTTPS only | True |
SESSION_COOKIE_HTTPONLY |
No JS access | True |
Full Configuration Example
from datetime import timedelta
app.config.update(
SECRET_KEY='super-secret-key',
SESSION_COOKIE_NAME='my_session',
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
PERMANENT_SESSION_LIFETIME=timedelta(days=7)
)
Making Sessions Last Longer
from datetime import timedelta
@app.route('/login')
def login():
session.permanent = True
app.permanent_session_lifetime = timedelta(days=30)
session['user'] = 'Alice'
return 'Logged in for 30 days!'
🍪 Cookie Operations: Loyalty Cards
Sessions vs Cookies
| Sessions | Cookies |
|---|---|
| Server remembers | Browser remembers |
| More secure | Less secure |
| Automatic | Manual |
Setting a Cookie
from flask import make_response
@app.route('/set-theme')
def set_theme():
resp = make_response('Theme saved!')
resp.set_cookie(
'theme', # name
'dark', # value
max_age=60*60*24*30 # 30 days
)
return resp
Reading a Cookie
from flask import request
@app.route('/get-theme')
def get_theme():
theme = request.cookies.get('theme', 'light')
return f'Your theme is: {theme}'
Deleting a Cookie
@app.route('/reset-theme')
def reset_theme():
resp = make_response('Theme reset!')
resp.delete_cookie('theme')
return resp
Cookie Options Explained
resp.set_cookie(
'user_pref',
'value123',
max_age=86400, # Seconds (1 day)
expires=None, # Specific date
path='/', # Available everywhere
domain=None, # Current domain only
secure=True, # HTTPS only
httponly=True, # No JavaScript
samesite='Lax' # CSRF protection
)
🌍 Timezone Handling: Knowing What Time It Is
The Problem
Your server is in New York. Your user is in Tokyo. What time is it?
Solution: Use UTC Everywhere
from datetime import datetime, timezone
# Always store in UTC
now_utc = datetime.now(timezone.utc)
# Store this in your database
session['last_visit'] = now_utc.isoformat()
Using pytz for Timezones
from datetime import datetime
import pytz
# Get user's timezone
user_tz = pytz.timezone('Asia/Tokyo')
# Convert UTC to user's time
utc_time = datetime.now(pytz.utc)
local_time = utc_time.astimezone(user_tz)
print(f"UTC: {utc_time}")
print(f"Tokyo: {local_time}")
Storing User’s Timezone
@app.route('/set-timezone')
def set_timezone():
# Store in session or cookie
session['timezone'] = 'America/New_York'
return 'Timezone saved!'
@app.route('/show-time')
def show_time():
import pytz
tz_name = session.get('timezone', 'UTC')
user_tz = pytz.timezone(tz_name)
now = datetime.now(pytz.utc)
local = now.astimezone(user_tz)
return f"Your time: {local.strftime('%I:%M %p')}"
graph TD A[Server Time UTC] --> B[Get User Timezone] B --> C[Convert to Local] C --> D[Display to User] D --> E[User Sees Their Time]
Quick Timezone Reference
| Task | Code |
|---|---|
| Get UTC now | datetime.now(timezone.utc) |
| Store timezone | session['tz'] = 'Asia/Tokyo' |
| Convert time | utc.astimezone(user_tz) |
| Format nicely | time.strftime('%I:%M %p') |
🎯 Putting It All Together
Here’s a complete example showing everything working together:
from flask import Flask, flash, session
from flask import request, make_response
from flask import render_template, redirect
from datetime import datetime, timedelta
import pytz
app = Flask(__name__)
app.secret_key = 'super-secret-key'
@app.route('/login', methods=['POST'])
def login():
# Set session
session.permanent = True
session['user'] = request.form['username']
session['timezone'] = 'America/New_York'
# Flash success message
flash('Welcome back!', 'success')
# Set cookie for preferences
resp = make_response(
redirect('/dashboard')
)
resp.set_cookie('theme', 'dark', max_age=2592000)
return resp
@app.route('/dashboard')
def dashboard():
# Read session
user = session.get('user', 'Guest')
# Read cookie
theme = request.cookies.get('theme', 'light')
# Convert time to user's zone
tz = pytz.timezone(
session.get('timezone', 'UTC')
)
local_time = datetime.now(pytz.utc).astimezone(tz)
return render_template(
'dashboard.html',
user=user,
theme=theme,
time=local_time
)
🚀 Quick Reference
| Task | Code |
|---|---|
| Flash message | flash('Hi!') |
| Flash with category | flash('Done!', 'success') |
| Set session | session['key'] = 'value' |
| Get session | session.get('key', 'default') |
| Clear session | session.clear() |
| Set cookie | resp.set_cookie('name', 'val') |
| Get cookie | request.cookies.get('name') |
| Delete cookie | resp.delete_cookie('name') |
| UTC time | datetime.now(timezone.utc) |
🎉 You Did It!
Now you know how to:
- ✅ Send one-time messages with flash
- ✅ Categorize messages by type
- ✅ Remember users with sessions
- ✅ Configure session security
- ✅ Store preferences in cookies
- ✅ Handle timezones correctly
Your Flask app can now remember users, communicate with them, and know what time it is in their world! 🌍