A simple backend system built with FastAPI that allows users to register, login, and manage their own tasks.
- User Authentication: Register and Login with JWT tokens
- Password Hashing: Secure password storage using bcrypt
- Role-based Access Control: Admin and User roles
- Task Management: Full CRUD operations for tasks
- Input Validation: Pydantic models for request/response validation
- Environment Variables: No hardcoded secrets
- Framework: FastAPI (Python)
- Database: SQLite (can be changed to PostgreSQL)
- ORM: SQLAlchemy
- Authentication: JWT (python-jose)
- Password Hashing: passlib with bcrypt
- Testing: pytest
BackendProject/
├── src/
│ ├── auth/
│ │ ├── jwt_handler.py # JWT token creation and verification
│ │ └── password.py # Password hashing utilities
│ ├── models/
│ │ ├── task.py # Task database model
│ │ └── user.py # User database model
│ ├── routes/
│ │ ├── auth.py # Authentication routes
│ │ ├── tasks.py # Task CRUD routes
│ │ └── users.py # User management routes
│ ├── schemas/
│ │ ├── task_schema.py # Pydantic schemas for tasks
│ │ └── user_schema.py # Pydantic schemas for users
│ ├── database.py # Database configuration
│ └── main.py # FastAPI app entry point
├── tests/
│ ├── test_auth.py # Authentication tests
│ ├── test_task.py # Task management tests
│ └── test_user.py # User management tests
├── .env # Environment variables
├── .env.example # Example environment variables
├── requirements.txt # Python dependencies
└── README.md # Project documentation
git clone <repository-url>
cd BackendProject# Windows
python -m venv venv
venv\Scripts\activate
# Linux/Mac
python3 -m venv venv
source venv/bin/activatepip install -r requirements.txtCopy .env.example to .env and update the values:
# Copy the example file
copy .env.example .envThe default configuration in .env:
SECRET_KEY=supersecretkey_change_this_in_production
DATABASE_URL=sqlite:///./tasks.db
ALGORITHM=HS256
TOKEN_EXPIRE_HOURS=2
uvicorn src.main:app --reloadThe API will be available at: http://127.0.0.1:8000
FastAPI provides automatic API documentation:
- Swagger UI:
http://127.0.0.1:8000/docs - ReDoc:
http://127.0.0.1:8000/redoc
# Run all tests
pytest
# Run tests with verbose output
pytest -v
# Run specific test file
pytest tests/test_auth.py -v
# Run tests and show coverage (if installed)
pytest --cov=src tests/| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/register |
Register a new user | No |
| POST | /auth/login |
Login and get JWT token | No |
| Method | Endpoint | Description | Auth Required | Role |
|---|---|---|---|---|
| GET | /users/me |
Get own profile | Yes | user/admin |
| GET | /users |
Get all users | Yes | admin |
| DELETE | /users/{id} |
Delete a user | Yes | admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /tasks |
Create a task | Yes |
| GET | /tasks |
Get all tasks (own or all if admin) | Yes |
| PUT | /tasks/{id} |
Update a task | Yes |
| DELETE | /tasks/{id} |
Delete a task | Yes |
curl -X POST "http://127.0.0.1:8000/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"role": "user"
}'Response:
{
"id": 1,
"email": "user@example.com",
"role": "user"
}curl -X POST "http://127.0.0.1:8000/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}curl -X POST "http://127.0.0.1:8000/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"title": "Complete assignment",
"description": "Finish the backend project"
}'curl -X GET "http://127.0.0.1:8000/tasks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"curl -X PUT "http://127.0.0.1:8000/tasks/1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"title": "Updated title",
"status": "completed"
}'curl -X DELETE "http://127.0.0.1:8000/tasks/1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"curl -X GET "http://127.0.0.1:8000/users/me" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"curl -X GET "http://127.0.0.1:8000/users" \
-H "Authorization: Bearer ADMIN_ACCESS_TOKEN"curl -X DELETE "http://127.0.0.1:8000/users/1" \
-H "Authorization: Bearer ADMIN_ACCESS_TOKEN"- ✅ Password hashing (bcrypt)
- ✅ JWT authentication
- ✅ Role-based access control (admin/user)
- ✅ Environment variables for secrets
- ✅ No credentials inside code
- ✅ Minimum 3 unit tests (password hashing, JWT)
- ✅ Minimum 2 API tests (auth, tasks, users)
The application uses SQLite by default. To change to PostgreSQL:
-
Update the
DATABASE_URLin.env:DATABASE_URL=postgresql://username:password@localhost/dbname -
Install PostgreSQL driver:
pip install psycopg2-binary
MIT License