A production-ready REST API for task and project management built with FastAPI, PostgreSQL, and modern best practices.
- Overview
- Features
- Tech Stack
- Live Demo
- Project Structure
- API Documentation
- Getting Started
- Environment Variables
- Database Schema
- API Endpoints
- Testing
- Deployment
- Contributing
Task Management API is a full-featured, production-ready REST API that provides comprehensive task and project management capabilities. Built with FastAPI and PostgreSQL, it implements modern authentication, advanced filtering, and follows industry best practices for scalability and security.
- ✅ Production-Ready: Fully tested, documented, and deployed
- ✅ Secure: JWT authentication with refresh tokens, password hashing, email verification
- ✅ Scalable: Async database operations, connection pooling, rate limiting
- ✅ Well-Documented: Interactive Swagger UI, comprehensive code comments
- ✅ Modern Stack: FastAPI, SQLAlchemy 2.0, Pydantic v2, Docker
- ✅ Best Practices: Clean architecture, repository pattern, type hints
- JWT-based authentication with access and refresh tokens
- Password hashing using bcrypt
- Email verification system
- Password reset flow with time-limited tokens
- Rate limiting to prevent abuse and brute force attacks
- CORS configuration for frontend integration
- Full CRUD operations for tasks
- Advanced filtering by status, priority, category, and date range
- Full-text search in title and description
- Pagination with total count and page info
- Task statistics (total, by status, overdue count)
- Due date tracking with overdue detection
- Priority levels: LOW, MEDIUM, HIGH, URGENT
- Status tracking: TODO, IN_PROGRESS, COMPLETED, ARCHIVED
- Custom categories with color coding
- Category-based filtering
- Task count per category
- Unique category names per user
- Performance metrics tracking
- Request/response logging
- Processing time headers
- Health check endpoint with database connectivity
- Slow request detection
- User registration with validation
- Profile management (view, update, delete)
- Password updates
- Account deletion
- PostgreSQL - Powerful, open-source relational database
- SQLAlchemy 2.0 - ORM with async support
- Alembic - Database migration tool
- asyncpg - Fast PostgreSQL driver for Python
- python-jose - JWT token generation/validation
- passlib - Password hashing with bcrypt
- SlowAPI - Rate limiting
- Pydantic v2 - Data validation and settings management
- email-validator - Email validation
- pytest - Testing framework
- pytest-asyncio - Async test support
- httpx - Async HTTP client for testing
- Faker - Fake data generation
https://task-management-api-a775.onrender.com
- Swagger UI: https://task-management-api-a775.onrender.com/docs
- ReDoc: https://task-management-api-a775.onrender.com/redoc
curl https://task-management-api-a775.onrender.com/health# Register a user
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"username": "testuser",
"password": "securepass123"
}'
# Login
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "securepass123"
}'task_management_api/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application & middleware
│ ├── config.py # Settings & environment variables
│ ├── database.py # Database connection & session
│ │
│ ├── models/ # SQLAlchemy ORM models
│ │ ├── __init__.py
│ │ ├── user.py # User model
│ │ ├── task.py # Task model with enums
│ │ └── category.py # Category model
│ │
│ ├── schemas/ # Pydantic request/response schemas
│ │ ├── __init__.py
│ │ ├── user.py # User schemas
│ │ ├── task.py # Task schemas
│ │ ├── category.py # Category schemas
│ │ ├── token.py # Token schemas
│ │ └── common.py # Common response schemas
│ │
│ ├── repositories/ # Data access layer
│ │ ├── __init__.py
│ │ ├── base.py # Base repository with CRUD
│ │ ├── user_repository.py # User data operations
│ │ ├── task_repository.py # Task data operations
│ │ └── category_repository.py # Category data operations
│ │
│ ├── services/ # Business logic layer
│ │ ├── __init__.py
│ │ ├── auth_service.py # Authentication logic
│ │ ├── user_service.py # User management logic
│ │ ├── task_service.py # Task management logic
│ │ └── category_service.py # Category management logic
│ │
│ ├── api/ # API routes
│ │ ├── __init__.py
│ │ ├── deps.py # Dependency injection
│ │ └── v1/
│ │ ├── __init__.py
│ │ ├── router.py # Main API router
│ │ ├── auth.py # Authentication endpoints
│ │ ├── users.py # User endpoints
│ │ ├── tasks.py # Task endpoints
│ │ └── categories.py # Category endpoints
│ │
│ ├── core/ # Core utilities
│ │ ├── __init__.py
│ │ ├── security.py # JWT & password hashing
│ │ ├── exceptions.py # Custom exceptions
│ │ ├── rate_limiter.py # Rate limiting config
│ │ ├── monitoring.py # Performance monitoring
│ │ └── logging_config.py # Logging configuration
│ │
│ └── utils/ # Helper functions
│ ├── __init__.py
│ └── email.py # Email utilities
│
├── tests/ # Test suite
│ ├── __init__.py
│ ├── conftest.py # Test fixtures
│ ├── test_auth.py # Authentication tests
│ ├── test_users.py # User tests
│ ├── test_tasks.py # Task tests
│ ├── test_categories.py # Category tests
│ ├── test_rate_limiting.py # Rate limit tests
│ ├── test_monitoring.py # Monitoring tests
│ └── test_error_handling.py # Error handling tests
│
├── alembic/ # Database migrations
│ ├── versions/ # Migration files
│ ├── env.py # Alembic environment
│ └── script.py.mako # Migration template
│
├── logs/ # Application logs (gitignored)
├── .env # Environment variables (gitignored)
├── .env.example # Environment template
├── .gitignore # Git ignore rules
├── alembic.ini # Alembic configuration
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose for local dev
├── render.yaml # Render deployment config
├── requirements.txt # Python dependencies
├── README.md # This file
└── DEPLOYMENT.md # Deployment guide
https://task-management-api-a775.onrender.com/api/v1
All endpoints except authentication and public endpoints require a JWT token.
Include in headers:
Authorization: Bearer <your_access_token>
Success Response:
{
"message": "Operation successful",
"data": { ... }
}Error Response:
{
"detail": "Error description",
"errors": {
"field": "Specific error message"
}
}| Endpoint Type | Limit | Purpose |
|---|---|---|
| Authentication | 3-10/min | Prevent brute force |
| Standard | 30/min | Normal operations |
| Global | 100/min | Overall protection |
Rate limit info in headers:
X-RateLimit-Limit: Maximum requestsX-RateLimit-Remaining: Remaining requestsX-RateLimit-Reset: Reset time
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /register |
Register new user | ❌ |
| POST | /login |
Login user | ❌ |
| POST | /refresh |
Refresh access token | ❌ |
| POST | /password-reset/request |
Request password reset | ❌ |
| POST | /password-reset/confirm |
Confirm password reset | ❌ |
| POST | /verify-email |
Verify email address | ❌ |
| POST | /resend-verification |
Resend verification email | ❌ |
| GET | /me |
Get current user info | ✅ |
| POST | /logout |
Logout user | ✅ |
📋 Authentication Examples
Register User:
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"username": "johndoe",
"password": "securepass123",
"full_name": "John Doe"
}'Login:
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe",
"password": "securepass123"
}'Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer"
}| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /me |
Get own profile | ✅ |
| PUT | /me |
Update own profile | ✅ |
| PUT | /me/password |
Update password | ✅ |
| DELETE | /me |
Delete account | ✅ |
| GET | /{user_id} |
Get user by ID | ✅ |
📋 User Examples
Get Profile:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/users/me" \
-H "Authorization: Bearer YOUR_TOKEN"Update Profile:
curl -X PUT "https://task-management-api-a775.onrender.com/api/v1/users/me" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"full_name": "John Updated Doe",
"email": "newemail@example.com"
}'| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | / |
Create new task | ✅ |
| GET | / |
Get tasks (with filters) | ✅ |
| GET | /{task_id} |
Get task by ID | ✅ |
| PUT | /{task_id} |
Update task | ✅ |
| DELETE | /{task_id} |
Delete task | ✅ |
| PATCH | /{task_id}/status |
Update task status | ✅ |
| PATCH | /{task_id}/priority |
Update task priority | ✅ |
| GET | /overdue |
Get overdue tasks | ✅ |
| GET | /statistics |
Get task statistics | ✅ |
Query Parameters for GET /:
skip: Number of records to skip (default: 0)limit: Max records to return (default: 10, max: 100)status: Filter by status (TODO, IN_PROGRESS, COMPLETED, ARCHIVED)priority: Filter by priority (LOW, MEDIUM, HIGH, URGENT)category_id: Filter by category UUIDsearch: Search in title and descriptiondue_date_from: Filter by due date (from)due_date_to: Filter by due date (to)
📋 Task Examples
Create Task:
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/tasks/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Complete project documentation",
"description": "Write comprehensive docs for the API",
"status": "TODO",
"priority": "HIGH",
"due_date": "2024-12-31T23:59:59"
}'Get Tasks with Filters:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/tasks/?status=TODO&priority=HIGH&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Complete project documentation",
"description": "Write comprehensive docs for the API",
"status": "TODO",
"priority": "HIGH",
"due_date": "2024-12-31T23:59:59",
"category_id": null,
"user_id": "456e7890-e89b-12d3-a456-426614174000",
"is_overdue": false,
"created_at": "2024-02-14T10:00:00",
"updated_at": "2024-02-14T10:00:00"
}
],
"total": 15,
"page": 1,
"page_size": 10,
"total_pages": 2
}Search Tasks:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/tasks/?search=documentation" \
-H "Authorization: Bearer YOUR_TOKEN"Get Statistics:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/tasks/statistics" \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"total": 45,
"by_status": {
"todo": 12,
"in_progress": 8,
"completed": 20,
"archived": 5
},
"overdue": 3
}| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | / |
Create category | ✅ |
| GET | / |
Get all categories | ✅ |
| GET | /{category_id} |
Get category by ID | ✅ |
| PUT | /{category_id} |
Update category | ✅ |
| DELETE | /{category_id} |
Delete category | ✅ |
| GET | /{category_id}/stats |
Get category stats | ✅ |
📋 Category Examples
Create Category:
curl -X POST "https://task-management-api-a775.onrender.com/api/v1/categories/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Work",
"color": "#FF5733"
}'Get All Categories:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/categories/" \
-H "Authorization: Bearer YOUR_TOKEN"Get Category Stats:
curl -X GET "https://task-management-api-a775.onrender.com/api/v1/categories/{category_id}/stats" \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"category": {
"id": "789e0123-e89b-12d3-a456-426614174000",
"name": "Work",
"color": "#FF5733",
"user_id": "456e7890-e89b-12d3-a456-426614174000",
"created_at": "2024-02-14T10:00:00",
"updated_at": "2024-02-14T10:00:00"
},
"task_count": 12
}| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /health |
Health check | ❌ |
| GET | /metrics |
Performance metrics | ❌ |
| POST | /metrics/reset |
Reset metrics | ❌ |
- Python 3.11+
- PostgreSQL 14+ (or Neon account)
- Git
- Docker (optional, for containerized development)
git clone https://github.com/YOUR_USERNAME/task-management-api.git
cd task-management-apiWindows (PowerShell):
python -m venv venv
.\venv\Scripts\Activate.ps1macOS/Linux:
python3 -m venv venv
source venv/bin/activatepip install -r requirements.txt# Copy example environment file
cp .env.example .env
# Edit .env with your configuration
# Windows: notepad .env
# macOS/Linux: nano .envGenerate SECRET_KEY:
python -c "import secrets; print(secrets.token_urlsafe(32))"Option A: Local PostgreSQL
# Create database
psql -U postgres
CREATE DATABASE task_management_dev;
CREATE USER task_admin WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE task_management_dev TO task_admin;
\qOption B: Neon (Serverless PostgreSQL)
- Sign up at neon.tech
- Create new project
- Copy connection string to
.env
alembic upgrade headuvicorn app.main:app --reloadAPI will be available at:
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down# Build image
docker build -t task-management-api .
# Run container
docker run -p 8000:8000 \
-e DATABASE_URL="your_database_url" \
-e SECRET_KEY="your_secret_key" \
task-management-apiCreate a .env file in the project root:
# Database
DATABASE_URL=postgresql+asyncpg://user:password@host:5432/dbname?ssl=require
DATABASE_URL_SYNC=postgresql://user:password@host:5432/dbname?sslmode=require
# Security
SECRET_KEY=your-secret-key-min-32-characters
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=15
REFRESH_TOKEN_EXPIRE_DAYS=7
# Application
APP_NAME=Task Management API
APP_VERSION=1.0.0
DEBUG=False
ENVIRONMENT=production
# CORS
BACKEND_CORS_ORIGINS=["https://your-frontend.com"]
# Rate Limiting
RATE_LIMIT_PER_MINUTE=100
AUTH_RATE_LIMIT_PER_MINUTE=5
# Email (Optional)
SMTP_TLS=True
SMTP_PORT=587
SMTP_HOST=smtp.gmail.com
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
EMAILS_FROM_EMAIL=noreply@taskmanagement.com
EMAILS_FROM_NAME=Task Management APISee .env.example for complete list.
┌─────────────────────┐
│ USERS │
├─────────────────────┤
│ id (UUID, PK) │
│ email (unique) │
│ username (unique) │
│ hashed_password │
│ is_active │
│ is_verified │
│ full_name │
│ created_at │
│ updated_at │
└─────────────────────┘
│ 1
│
│ N
┌────────┴────────────────────┐
│ │ │
│ 1 │ 1 │
│ │ │
│ N │ │ N
┌────────▼────────┐ ┌────────▼────────┐
│ CATEGORIES │ │ TASKS │
├─────────────────┤ ├─────────────────┤
│ id (UUID, PK) │ │ id (UUID, PK) │
│ name │ │ title │
│ color │ │ description │
│ user_id (FK) │ │ status (enum) │
│ created_at │ │ priority (enum) │
│ updated_at │ │ due_date │
└─────────────────┘ │ user_id (FK) │
│ 1 │ category_id(FK) │
│ │ created_at │
│ N │ updated_at │
└───────────┤ is_overdue │
└─────────────────┘
User Model:
- UUID primary key
- Email and username (unique, indexed)
- Password (hashed with bcrypt)
- Active and verified status
- Timestamps
Task Model:
- UUID primary key
- Title and description
- Status: TODO, IN_PROGRESS, COMPLETED, ARCHIVED
- Priority: LOW, MEDIUM, HIGH, URGENT
- Optional due date
- Foreign keys: user_id, category_id
- Computed field: is_overdue
Category Model:
- UUID primary key
- Name (unique per user)
- Color (hex code)
- Foreign key: user_id
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run with coverage
pytest --cov=app tests/
# Run specific test file
pytest tests/test_auth.py -v
# Generate HTML coverage report
pytest --cov=app --cov-report=html tests/Current coverage: ~87%
tests/test_auth.py ............................ 33%
tests/test_users.py ....... 47%
tests/test_tasks.py ........................ 78%
tests/test_categories.py ............ 90%
tests/test_rate_limiting.py ... 93%
tests/test_monitoring.py ..... 98%
tests/test_error_handling.py .... 100%
======================== 85 passed in 18.45s ========================
- Push to GitHub:
git push origin main-
Create Web Service on Render:
- Connect GitHub repository
- Runtime: Docker
- Region: Choose nearest
- Plan: Free
-
Set Environment Variables in Render dashboard
-
Deploy:
- Automatic deployment on git push
- Manual deploy option available
Heroku
# Install Heroku CLI
# Login
heroku login
# Create app
heroku create your-app-name
# Add PostgreSQL
heroku addons:create heroku-postgresql:mini
# Set environment variables
heroku config:set SECRET_KEY=your_secret_key
# Deploy
git push heroku mainAWS (EC2 + RDS)
- Create RDS PostgreSQL instance
- Launch EC2 instance
- Install Docker
- Pull and run container
- Configure security groups
- Set up domain and SSL
DigitalOcean
- Create PostgreSQL database
- Create App Platform app
- Connect GitHub repository
- Set environment variables
- Deploy
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature- Make your changes and commit:
git commit -m "Add amazing feature"- Push to your fork:
git push origin feature/amazing-feature- Open a Pull Request
- Follow PEP 8 style guide
- Add tests for new features
- Update documentation
- Keep commits atomic and descriptive
Your Name
- GitHub: ravigupta97
- LinkedIn: Ravi Gupta
- Email: gupta_ravi@outlook.in
- FastAPI - Amazing web framework
- SQLAlchemy - Powerful ORM
- Pydantic - Data validation
- Render - Easy deployment
- Neon - Serverless PostgreSQL
If you have any questions or need help:
- 💬 Issues: GitHub Issues
- 📖 Documentation: API Docs
Built with ❤️ using FastAPI and PostgreSQL