A small user management API built with FastAPI, PostgreSQL, and SQLAlchemy.
- User registration and authentication (HTTP Basic Auth)
- Role-based access control (admin/regular user)
- First registered user automatically becomes admin
- Admin can manage all users (activate, deactivate, delete)
- Regular users can view and update their own profile
Run the full stack with a single command:
docker compose up -dThis starts:
- PostgreSQL database
- FastAPI application (with automatic migrations)
API available at http://localhost:8000
Stop and clean up:
# Stop containers
docker compose down
# Stop and remove volumes (database data)
docker compose down -v
# Full cleanup (containers, volumes, networks, images)
docker compose down -v --rmi all- Python 3.13+
- uv package manager
- Docker (for PostgreSQL)
# Install dependencies
uv sync
# Activate virtual environment
source .venv/bin/activate
# Start PostgreSQL only
docker compose up -d db
# Copy environment file
cp .env.example .env
# Run database migrations
alembic upgrade head
# Start the app
uvicorn app.main:app --reloadAPI available at http://localhost:8000
Connect to the database with auto-completion and syntax highlighting:
pgcli postgresql://postgres:postgres@localhost:5432/user_managementCommon commands:
| Command | Description |
|---|---|
\dt |
List tables |
\d users |
Describe users table |
SELECT * FROM users LIMIT 10; |
Query users |
\q |
Quit |
| Method | Path | Description | Access |
|---|---|---|---|
| POST | /users | Register new user | Public |
| GET | /users/me | Get current user profile | Authenticated |
| PUT | /users/me | Update current user profile | Authenticated |
| GET | /users | List all users | Admin only |
| GET | /users/{id} | Get user by ID | Admin only |
| PATCH | /users/{id}/activate | Activate user | Admin only |
| PATCH | /users/{id}/deactivate | Deactivate user | Admin only |
| DELETE | /users/{id} | Delete user | Admin only |
The API uses HTTP Basic Authentication. The first registered user automatically becomes an admin.
# First user becomes admin
curl -X POST http://localhost:8000/users \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "adminpass123"}'
# Second user is regular user
curl -X POST http://localhost:8000/users \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "userpass123"}'# Get own profile
curl -u [email protected]:userpass123 http://localhost:8000/users/me
# Update own profile
curl -X PUT -u [email protected]:userpass123 http://localhost:8000/users/me \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'# List all users
curl -u [email protected]:adminpass123 http://localhost:8000/users
# Get user by ID
curl -u [email protected]:adminpass123 http://localhost:8000/users/2
# Deactivate user
curl -X PATCH -u [email protected]:adminpass123 http://localhost:8000/users/2/deactivate
# Activate user
curl -X PATCH -u [email protected]:adminpass123 http://localhost:8000/users/2/activate
# Delete user
curl -X DELETE -u [email protected]:adminpass123 http://localhost:8000/users/2# Apply migrations
alembic upgrade head
# Create new migration after model changes
alembic revision --autogenerate -m "description"
# Rollback last migration
alembic downgrade -1# Run all tests
pytest
# Run with verbose output
pytest -v
# Run only unit tests (fast, no Docker required)
pytest tests/unit/
# Run only integration tests
pytest tests/integration/- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
user-management-api/
├── app/
│ ├── main.py # FastAPI application
│ ├── dependencies.py # Auth dependencies
│ ├── core/
│ │ ├── config.py # Settings
│ │ ├── database.py # Database setup
│ │ └── security.py # Password hashing
│ ├── models/
│ │ └── user.py # SQLAlchemy models
│ ├── schemas/
│ │ └── user.py # Pydantic schemas
│ ├── services/
│ │ └── user.py # Business logic
│ └── routers/
│ └── users.py # API endpoints
├── alembic/ # Database migrations
├── tests/
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── scripts/
│ └── entrypoint.sh # Docker entrypoint
├── Dockerfile
├── docker-compose.yml
└── pyproject.toml