A RESTful web application built with Flask and PostgreSQL, providing user management and product management APIs with secure authentication.
hh
- Python 3.9+
- Docker and Docker Compose
- Git
- curl or Postman (for API testing)
- Operating System: Ubuntu 24.04 LTS (or compatible)
- Programming Language: Python 3.11
- Database: PostgreSQL 14
- Framework: Flask with SQLAlchemy ORM
webapp/
├── app/
│ ├── __init__.py # Flask application factory
│ ├── config.py # Configuration management
│ ├── controllers/ # API route handlers
│ │ ├── health_controller.py # Health check endpoints
│ │ ├── user_controller.py # User management endpoints
│ │ └── product_controller.py # Product management endpoints
│ ├── models/ # Database models
│ │ ├── health_check.py # Health check model
│ │ ├── user.py # User model
│ │ └── product.py # Product model
│ ├── middleware/ # Authentication middleware
│ ├── utils/ # Utility functions
│ └── validators/ # Input validation
├── tests/ # Unit and integration tests
├── migrations/ # Database migration files
├── requirements.txt # Python dependencies
├── Dockerfile # Container configuration
├── docker-compose.yml # Multi-container orchestration
├── .env.example # Environment variables template
└── README.md # This file
git clone <repository-url>
cd webapp# Copy environment template
cp .env.example .env
# Edit .env file with your configuration
nano .envConfigure the following variables in your .env file:
# Database Configuration
POSTGRES_DB=webapp_db
POSTGRES_USER=webapp_user
POSTGRES_PASSWORD=your_secure_password
# Application Configuration
DATABASE_URL=postgresql://webapp_user:your_secure_password@localhost:5432/webapp_db
SECRET_KEY=your-secret-key-here
PORT=8000# Build and start all services
docker-compose up --build
# Or run in detached mode
docker-compose up --build -d# Check service status
docker-compose ps
# View application logs
docker-compose logs web
# Check database connectivity
docker-compose logs dbdocker-compose down# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt# Ensure PostgreSQL is running locally
sudo service postgresql start
# Create database and user (if not exists)
sudo -u postgres createdb webapp_db
sudo -u postgres createuser webapp_user
sudo -u postgres psql -c "ALTER USER webapp_user WITH PASSWORD 'your_password';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE webapp_db TO webapp_user;"# Initialize database tables
python run.pyThe application will be available at http://localhost:8000
http://localhost:8000
The API uses HTTP Basic Authentication for protected endpoints.
- GET
/healthz- Application health status - Returns 200 OK when healthy, 503 Service Unavailable when unhealthy
- POST
/v1/user- Create a new user account
- GET
/v1/product/{productId}- Get product details
- GET
/v1/user/{userId}- Get user information (own account only) - PUT
/v1/user/{userId}- Update user information (own account only)
- POST
/v1/product- Create a new product - PUT
/v1/product/{productId}- Update product (owner only) - PATCH
/v1/product/{productId}- Partially update product (owner only) - DELETE
/v1/product/{productId}- Delete product (owner only)
- Content-Type:
application/json - All timestamps in UTC ISO 8601 format
- Passwords are never returned in responses
# Run all tests
TESTING=1 pytest tests/ -v
# Run specific test file
TESTING=1 pytest tests/test_users.py -v
# Run with coverage
TESTING=1 pytest tests/ --cov=app --cov-report=htmlcurl -X POST http://localhost:8000/v1/user \
-H "Content-Type: application/json" \
-d '{
"username": "[email protected]",
"password": "password123",
"first_name": "John",
"last_name": "Doe"
}'curl -X GET http://localhost:8000/v1/user/1 \
-H "Authorization: Basic $(echo -n '[email protected]:password123' | base64)"curl -X POST http://localhost:8000/v1/product \
-H "Authorization: Basic $(echo -n '[email protected]:password123' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "Sample Product",
"description": "A sample product",
"sku": "SP-001",
"manufacturer": "Sample Corp",
"quantity": 10
}'CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
account_created TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
account_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
sku VARCHAR(100) UNIQUE NOT NULL,
manufacturer VARCHAR(255) NOT NULL,
quantity INTEGER DEFAULT 0,
date_added TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
date_last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
owner_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE
);CREATE TABLE health_checks (
check_id SERIAL PRIMARY KEY,
check_datetime TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);- Password Security: BCrypt hashing with automatic salt generation
- Authentication: HTTP Basic Authentication for API access
- Authorization: Users can only access their own data
- Input Validation: Comprehensive validation for all user inputs
- SQL Injection Protection: SQLAlchemy ORM prevents SQL injection
- XSS Protection: Proper input sanitization and output encoding
DATABASE_URL: PostgreSQL connection stringSECRET_KEY: Flask application secret keyPORT: Application port (default: 8000)TESTING: Set to '1' for test environment
- Web service runs on port 8000
- PostgreSQL service runs on port 5432
- Persistent volume for database data
- Automatic service dependency management
# Check database service status
docker-compose logs db
# Verify database credentials
docker-compose exec db psql -U webapp_user -d webapp_db# Check application logs
docker-compose logs web
# Rebuild containers
docker-compose down
docker-compose up --build# Change port in .env file
PORT=8001
# Or stop conflicting services
sudo lsof -i :8000docker-compose exec db psql -U healthcheck_user -d healthcheck_db-- List all users
SELECT id, email, first_name, last_name FROM users;
-- List all products
SELECT id, name, sku, owner_user_id FROM products;
-- View health check logs
SELECT * FROM health_checks ORDER BY check_datetime DESC LIMIT 10;- Create a feature branch:
git checkout -b feature/your-feature - Make your changes
- Run tests:
TESTING=1 pytest tests/ -v - Commit changes:
git commit -m "Description of changes" - Push branch:
git push origin feature/your-feature - Create pull request
- Update models if database schema changes are needed
- Add controllers for new endpoints
- Implement validation logic
- Add comprehensive tests
- Update API documentation
- Follow PEP 8 coding standards
- Write comprehensive tests for new features
- Update documentation for API changes
- Ensure all tests pass before submitting pull requests
- Use meaningful commit messages
This project is developed for educational purposes as part of the CSYE 6225 Cloud Computing course.