Assignment Overview
In this assignment, you will build a complete Task Manager Web Application called FlaskTodo. This comprehensive project requires you to apply ALL concepts from Module 10: Flask basics, routing, templates, forms, sessions, database integration, and RESTful APIs.
Routes & Views (10.1)
URL routing, view functions, blueprints, HTTP methods, redirects
Templates & Forms (10.2)
Jinja2 templates, form handling, validation, flash messages
Database & Auth (10.3)
SQLAlchemy ORM, CRUD operations, user authentication, sessions
The Scenario
TaskFlow Solutions
You have been hired as a Python Web Developer at TaskFlow Solutions, a productivity startup that needs a simple yet powerful task management application. The product manager has given you this brief:
"We need a web application where users can register, login, and manage their personal tasks. Each task should have a title, description, due date, priority, and status. Users should only see their own tasks. We also need a simple API for our mobile team to integrate with."
Your Task
Create a Flask web application called FlaskTodo that implements a complete
task management system. Your application must include user authentication, full CRUD
operations for tasks, a responsive UI with Bootstrap, and RESTful API endpoints.
Required Project Structure
flask-todo/
├── app/
│ ├── __init__.py # Flask app factory
│ ├── models.py # SQLAlchemy models (User, Task)
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── auth.py # Authentication routes (login, register, logout)
│ │ ├── tasks.py # Task CRUD routes
│ │ └── api.py # RESTful API endpoints
│ ├── templates/
│ │ ├── base.html # Base template with Bootstrap
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ └── register.html
│ │ └── tasks/
│ │ ├── index.html # Task list view
│ │ ├── create.html # Create task form
│ │ └── edit.html # Edit task form
│ └── static/
│ └── css/
│ └── style.css # Custom styles (minimal)
├── config.py # Configuration settings
├── run.py # Application entry point
├── requirements.txt # Python dependencies
└── README.md # Project documentation
Requirements
Your FlaskTodo application must implement ALL of the following features.
Each feature is mandatory and will be tested individually.
Database Models
Create SQLAlchemy models in models.py:
- User Model: id, username (unique), email (unique), password_hash, created_at
- Task Model: id, title, description, due_date, priority (Low/Medium/High), status (Pending/In Progress/Completed), user_id (foreign key), created_at, updated_at
- Implement password hashing using
werkzeug.security
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(256), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
tasks = db.relationship('Task', backref='owner', lazy=True)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
class Task(db.Model):
# Define all required columns and relationships
pass
User Authentication
Implement authentication routes in routes/auth.py:
GET/POST /register- User registration with form validationGET/POST /login- User login with Flask-LoginGET /logout- User logout (requires login)- Use Flask-Login for session management
- Show appropriate flash messages for success/error states
from flask import Blueprint, render_template, redirect, url_for, flash, request
from flask_login import login_user, logout_user, login_required
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
# Validate form data
# Check if username/email already exists
# Create new user
# Flash success message
# Redirect to login
pass
return render_template('auth/register.html')
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
# Implement login logic
pass
Task CRUD Operations
Implement task management routes in routes/tasks.py:
GET /tasks- List all tasks for logged-in user (with filtering options)GET/POST /tasks/create- Create new task form and submissionGET/POST /tasks/<id>/edit- Edit existing taskPOST /tasks/<id>/delete- Delete taskPOST /tasks/<id>/toggle- Toggle task status- All routes must be protected with
@login_required - Users can only access their own tasks
Jinja2 Templates
Create responsive templates using Bootstrap 5:
- base.html: Navigation bar, flash messages container, footer, Bootstrap CDN links
- login.html & register.html: Forms with validation feedback
- tasks/index.html: Task list with cards/table, filter buttons, action buttons
- tasks/create.html & edit.html: Forms for task creation/editing
- Use template inheritance (
{% extends "base.html" %}) - Use Jinja2 macros for reusable form components
<!-- base.html example -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}FlaskTodo{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<!-- Navigation content -->
</nav>
<main class="container my-4">
{% with messages = get_flashed_messages(with_categories=true) %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</body>
</html>
RESTful API Endpoints
Create API routes in routes/api.py that return JSON:
GET /api/tasks- List all tasks for authenticated userPOST /api/tasks- Create new task (JSON body)GET /api/tasks/<id>- Get single task detailsPUT /api/tasks/<id>- Update taskDELETE /api/tasks/<id>- Delete task- Return appropriate HTTP status codes (200, 201, 400, 401, 404)
- Use
jsonify()for JSON responses
from flask import Blueprint, jsonify, request
from flask_login import login_required, current_user
api_bp = Blueprint('api', __name__, url_prefix='/api')
@api_bp.route('/tasks', methods=['GET'])
@login_required
def get_tasks():
tasks = Task.query.filter_by(user_id=current_user.id).all()
return jsonify({
'tasks': [task.to_dict() for task in tasks]
}), 200
@api_bp.route('/tasks', methods=['POST'])
@login_required
def create_task():
data = request.get_json()
# Validate data
# Create task
# Return created task with 201 status
pass
Form Validation & Error Handling
Implement proper validation and error handling:
- Validate all form inputs on the server side
- Show validation errors next to form fields
- Handle 404 errors with a custom error page
- Handle 500 errors gracefully
- Prevent duplicate usernames and emails
Configuration & App Factory
Use proper Flask application structure:
- Create app factory pattern in
app/__init__.py - Use
config.pyfor configuration (SECRET_KEY, DATABASE_URI, etc.) - Register all blueprints properly
- Initialize extensions (SQLAlchemy, LoginManager)
# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import Config
db = SQLAlchemy()
login_manager = LoginManager()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = 'auth.login'
from app.routes.auth import auth_bp
from app.routes.tasks import tasks_bp
from app.routes.api import api_bp
app.register_blueprint(auth_bp)
app.register_blueprint(tasks_bp)
app.register_blueprint(api_bp)
with app.app_context():
db.create_all()
return app
Additional Features (Bonus)
Implement these optional features for bonus points:
- Task Filtering: Filter by status, priority, or due date
- Task Sorting: Sort by due date, priority, or created date
- Search: Search tasks by title or description
- Dashboard: Show task statistics (total, completed, pending)
- Dark Mode: Toggle between light and dark themes
Submission
Create a public GitHub repository with the exact name shown below:
Required Repository Name
flask-todo-app
Required Files
flask-todo-app/
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── auth.py
│ │ ├── tasks.py
│ │ └── api.py
│ ├── templates/
│ │ ├── base.html
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ └── register.html
│ │ └── tasks/
│ │ ├── index.html
│ │ ├── create.html
│ │ └── edit.html
│ └── static/
│ └── css/
│ └── style.css
├── config.py
├── run.py
├── requirements.txt
├── .gitignore
└── README.md
README.md Must Include:
- Your full name and submission date
- Project description and features implemented
- Setup instructions (how to install and run)
- API documentation (list all endpoints with examples)
- Screenshots of your application (at least 3)
requirements.txt Must Include:
Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Login==0.6.3
Werkzeug==3.0.1
Do Include
- All required routes and features working
- Proper model relationships
- Clean, responsive Bootstrap UI
- Form validation with error messages
- Flash messages for user feedback
- Working API endpoints with proper status codes
- README.md with screenshots
Do Not Include
- Database files (*.db, *.sqlite)
- Virtual environment folders (venv/, env/)
- __pycache__ or *.pyc files
- Hardcoded credentials or SECRET_KEY
- .env files (use .env.example instead)
- IDE configuration files
Enter your GitHub username - we'll verify your repository automatically
Grading Rubric
Your assignment will be graded on the following criteria:
| Criteria | Points | Description |
|---|---|---|
| Database Models | 30 | User and Task models with proper relationships, password hashing, and timestamps |
| Authentication System | 40 | Working registration, login, logout with Flask-Login, session management |
| Task CRUD Operations | 50 | Create, read, update, delete tasks with proper authorization checks |
| Templates & UI | 40 | Clean Bootstrap UI, template inheritance, flash messages, responsive design |
| RESTful API | 40 | All 5 API endpoints working with proper JSON responses and status codes |
| Form Validation | 20 | Server-side validation, error messages, duplicate checks |
| Code Quality | 30 | App factory pattern, blueprints, configuration, clean organization, comments |
| Total | 250 | |
| Bonus Features | +25 | Filtering, sorting, search, dashboard, dark mode (5 pts each) |
Ready to Submit?
Make sure you have completed all requirements and reviewed the grading rubric above.
Submit Your AssignmentWhat You Will Practice
Flask Routing (10.1)
URL routing, view functions, blueprints, HTTP methods, redirects, URL building
Jinja2 Templates (10.2)
Template inheritance, control flow, filters, macros, form rendering, flash messages
SQLAlchemy ORM (10.3)
Model definitions, relationships, queries, CRUD operations, migrations
User Authentication
Flask-Login, password hashing, session management, login_required decorator
Pro Tips
Flask Best Practices
- Use app factory pattern for better testing
- Keep routes organized with blueprints
- Never commit SECRET_KEY to version control
- Use environment variables for configuration
Database Tips
- Always check user ownership before operations
- Use relationship backref for cleaner queries
- Add database indexes for frequently queried columns
- Handle IntegrityError for duplicates
Security Tips
- Always hash passwords - never store plain text
- Use CSRF protection for forms
- Validate and sanitize all user input
- Check authorization on every protected route
Common Mistakes
- Forgetting to call db.create_all()
- Not using @login_required on protected routes
- Returning HTML from API endpoints
- Not handling form validation errors