A resilient URL shortener service built for production.
Tech Stack:
CI Status:
- Prerequisites
- Configuration
- Quick Start
- API Endpoints
- Project Structure
- Running Tests
- Load Testing
- Monitoring & Observability
- Deployment
- AI Usage
- Architecture
- Decision Log
- License
A fast Python package manager that handles Python versions, virtual environments, and dependencies automatically — no manual python -m venv needed.
macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | shWindows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Note
For other install methods, see the uv installation docs.
| Command | What it does |
|---|---|
uv sync |
Install all dependencies (creates .venv automatically) |
uv run <script> |
Run a script inside the project virtualenv |
uv add <package> |
Add a new dependency |
uv remove <package> |
Remove a dependency |
Required for running infrastructure services (PostgreSQL, Valkey) and the full monitoring stack.
Copy .env.example to .env before running anything:
cp .env.example .env| Variable | Default | Description |
|---|---|---|
DATABASE_HOST |
localhost |
PostgreSQL host |
DATABASE_PORT |
5432 |
PostgreSQL port |
DATABASE_NAME |
hackathon_db |
Database name |
DATABASE_USER |
postgres |
Database user |
DATABASE_PASSWORD |
postgres |
Database password |
REDIS_URL |
— | Valkey/Redis connection URL (optional) |
LOG_LEVEL |
INFO |
Logging verbosity |
Runs only PostgreSQL + Valkey via Docker. You run the Flask app yourself with uv.
1. Start dev dependencies
docker compose -f compose.dev.yml up -d2. Install dependencies
uv sync3. Configure environment
cp .env.example .env4. Run the server
uv run run.py5. Verify
curl http://localhost:5000/health
# → {"status":"ok"}6. Stop when done
docker compose -f compose.dev.yml downEverything containerized: app, nginx, Prometheus, Grafana, Loki, and Alertmanager.
1. Start all services
docker compose up --build -d2. Verify
curl http://localhost/health
# → {"status":"ok"}3. Stop when done
docker compose downNote
Access the app at http://localhost via nginx. Monitoring URLs are listed in the Monitoring & Observability section.
Full interactive docs available at /apidocs/ via Swagger UI, or try the live API at https://pipeliedev.github.io/pe-hackathon/
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/metrics |
GET | Prometheus metrics |
/users |
POST | Register a user |
/users |
GET | List users |
/urls |
POST | Create a shortened URL |
/urls |
GET | List URLs |
/urls/<short_code> |
GET | Redirect to original URL |
/urls/<short_code>/stats |
GET | Get URL statistics |
/events |
GET | List analytics events |
mlh-pe-hackathon/
├── app/
│ ├── __init__.py # App factory, Prometheus metrics
│ ├── database.py # DatabaseProxy, BaseModel, connection hooks
│ ├── cache.py # Valkey/Redis caching layer
│ ├── logging.py # Structured JSON logging
│ ├── models/
│ │ ├── user.py
│ │ ├── url.py
│ │ └── event.py
│ └── routes/
│ ├── __init__.py # register_routes()
│ ├── users.py
│ ├── urls.py
│ └── events.py
├── tests/ # Unit & integration tests
├── monitoring/ # Prometheus, Grafana, Alertmanager configs
├── k8s/ # Kubernetes manifests
├── compose.yml # Full stack (app + monitoring)
├── compose.dev.yml # Dev only (DB + Valkey)
├── locustfile.py # Load testing
└── scripts/seed.py # Seed data script
Make sure dev dependencies are running before starting. If not, run docker compose -f compose.dev.yml up -d first.
1. Create test database (first time only)
docker exec pe-hackathon-db-1 psql -U postgres -c "CREATE DATABASE hackathon_test_db;"2. Run all tests
uv run pytest3. Run with coverage (70% minimum required)
uv run pytest --cov=app --cov-report=term-missing --cov-fail-under=704. Unit tests only (no DB needed)
uv run pytest tests/unit5. Integration tests only
uv run pytest tests/integration6. Run a specific test
uv run pytest tests/integration/test_users.py::test_name -vuv run locust -f locustfile.py --headless -u 50 -r 10 --run-time 60s --host http://localhost:5000Available when running the full stack via docker compose up --build.
| Service | URL | Notes |
|---|---|---|
| App | http://localhost | Via nginx load balancer |
| Prometheus | http://localhost:9090 | |
| Grafana | http://localhost:30030 | Default credentials: admin / admin |
| Alertmanager | http://localhost:9093 | |
| Loki | http://localhost:3100 |
Pre-configured dashboard includes: request rate by HTTP method, p99 latency, error rates, and application resource usage.
| Alert | Condition |
|---|---|
HighErrorRateCritical |
Error rate > 5% |
HighAppCPU |
CPU usage > 80% |
HighMemory |
Memory usage > 80% |
NoRequests |
No traffic for 5 minutes |
See k8s-setup.md for the full K3s cluster setup guide.
Deploy
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/postgres-cluster.yaml
kubectl apply -f k8s/app-deployment.yaml
kubectl apply -f k8s/app-service.yamlDeploy monitoring
./scripts/deploy-monitoring.shCheck status
kubectl get pods -n url-shortenerRollback
kubectl rollout undo deployment/url-shortener -n url-shortener
kubectl rollout status deployment/url-shortener -n url-shortenerMIT


