04261c59ccbd893b8ca49bc4b7198673ecee17ac
URL Shortener
A minimal URL shortener written in pure Python 3.8+ (zero third-party dependencies) backed by SQLite.
Quick start
Run locally
python urlshort.py config.json
Run with Docker Compose
Edit config.json first (especially api_key and base_url), then:
docker compose up --build
The SQLite database is stored in ./data/urlshort.db on the host — it survives container restarts.
Configuration (config.json)
| Key | Required | Default | Description |
|---|---|---|---|
base_url |
✅ | — | Public base URL used in generated short URLs |
short_length |
✅ | — | Character length of auto-generated codes |
api_key |
✅ | — | Secret key to protect write/read operations |
host |
"0.0.0.0" |
Bind address | |
port |
8080 |
Bind port | |
db_path |
"data/urlshort.db" |
Path to the SQLite database file |
Authentication
All /api/* endpoints require the API key.
Pass it as a Bearer token in the Authorization header or as a query parameter:
Authorization: Bearer <api_key>
# or
?api_key=<api_key>
API Reference
GET /
Health check.
Response 200
{ "status": "ok", "service": "url-shortener" }
POST /api/shorten 🔒
Create a new short URL.
Request body
{
"url": "https://example.com/very/long/path",
"custom_code": "mycode" // optional
}
Response 201
{
"short_code": "aB3xYz",
"short_url": "http://localhost:8080/aB3xYz",
"original_url": "https://example.com/very/long/path",
"created_at": 1710000000
}
GET /api/urls 🔒
List all short URLs, newest first.
Response 200
{
"count": 2,
"urls": [
{
"short_code": "aB3xYz",
"short_url": "http://localhost:8080/aB3xYz",
"original_url": "https://example.com",
"created_at": 1710000000,
"visit_count": 5
}
]
}
GET /api/urls/<code> 🔒
Get metadata for a single short code.
Response 200 — same shape as one item from the list above.
Response 404 — code not found.
DELETE /api/urls/<code> 🔒
Delete a short URL entry.
Response 200
{ "message": "Deleted 'aB3xYz'" }
GET /<code>
Redirect to the original URL (HTTP 302).
Increments visit_count on each hit.
Example with curl
# Shorten a URL
curl -X POST http://localhost:8080/api/shorten \
-H "Authorization: Bearer change-this-secret-key" \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com"}'
# Follow the redirect
curl -L http://localhost:8080/aB3xYz
# List all URLs
curl http://localhost:8080/api/urls \
-H "Authorization: Bearer change-this-secret-key"
# Delete a URL
curl -X DELETE http://localhost:8080/api/urls/aB3xYz \
-H "Authorization: Bearer change-this-secret-key"
Languages
CSS
84.8%
Rust
10.4%
JavaScript
3.9%
HTML
0.5%
Shell
0.3%
Other
0.1%