A production-ready REST API for managing todos with JWT authentication, PostgreSQL persistence, and Redis-based rate limiting.
- RESTful API for todo management
- JWT-based authentication
- PostgreSQL database with Alembic migrations
- Redis-based rate limiting
- Comprehensive test suite
- Docker deployment ready
- OpenAPI/Swagger documentation
- Python Development Guide - Coding standards and best practices
- Rate Limiting Guide - Comprehensive rate limiting documentation
- PRP Framework - Product Requirement Prompt methodology
http://localhost:8000/api/v1
All endpoints except /auth/register
and /auth/login
require JWT authentication.
Include the JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
The API implements rate limiting to prevent abuse and ensure fair usage.
All authenticated users have the following limits:
Endpoint Category | Limit |
---|---|
Authentication | 5 requests/minute |
Todo Operations | 60 requests/minute |
Bulk Operations | 5 requests/minute |
Rate limits can be configured via environment variables:
RATE_LIMIT_PER_MINUTE=100
RATE_LIMIT_TODO_CREATE=30/minute
For detailed information, see the Rate Limiting Guide.
Note: The API currently uses uniform rate limiting for all users. Tier-based limiting may be implemented in future versions.
POST /auth/register
Create a new user account.
Rate Limit: 10 requests per hour
Request Body:
{
"email": "[email protected]",
"password": "securepassword",
"full_name": "John Doe"
}
POST /auth/login
Authenticate and receive a JWT token.
Rate Limit: 5 requests per minute
Request Body:
{
"username": "[email protected]",
"password": "securepassword"
}
All todo endpoints require authentication and are subject to the default rate limits (100/min, 1000/hour).
GET /todos
Retrieve all todos for the authenticated user.
POST /todos
Create a new todo.
GET /todos/{todo_id}
Retrieve a specific todo.
PUT /todos/{todo_id}
Update an existing todo.
DELETE /todos/{todo_id}
Delete a todo.
All category endpoints require authentication and are subject to the default rate limits (100/min, 1000/hour).
GET /categories
Retrieve all categories for the authenticated user.
POST /categories
Create a new category.
- Clone the repository
- Navigate to the docker directory:
cd todo-api/docker
- Start the services:
docker-compose up
This will start:
- PostgreSQL database
- Redis server
- Todo API application
-
Install dependencies:
pip install -r requirements.txt
-
Set up environment variables:
cp .env.example .env # Edit .env with your configuration
-
Run database migrations:
alembic upgrade head
-
Start the application:
uvicorn app.main:app --reload
The SECRET_KEY is critical for JWT token security and must meet strict entropy requirements.
Generate a cryptographically secure key:
# Recommended: Use the provided script
python scripts/generate_secret_key.py
# Alternative methods:
# Using Python
python -c "import secrets; print(secrets.token_urlsafe(64))"
# Using OpenSSL
openssl rand -base64 64 | tr -d '
='
Set in environment:
# .env file
SECRET_KEY="your-generated-64-character-key"
Production Requirements:
- Minimum 64 characters length
- Minimum 16 unique characters (entropy check)
- Cryptographically secure random generation
- No weak patterns (repeated chars, dictionary words)
- Unique per environment
- Never commit to git
Run the test suite:
pytest tests/ -v
With coverage:
pytest tests/ -v --cov=app --cov-report=html
Interactive API documentation is available at:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI Schema: http://localhost:8000/openapi.json
The API uses standard HTTP status codes and returns errors in the following format:
{
"detail": "Error message description"
}
Common status codes:
400
- Bad Request401
- Unauthorized403
- Forbidden404
- Not Found422
- Validation Error429
- Too Many Requests (Rate Limit Exceeded)500
- Internal Server Error