A zero-dependency Python URL shortener with SQLite persistence, click tracking, QR codes, and a built-in JSON API server.
- Short code generation -- base62 encoding with collision avoidance
- Custom aliases -- choose your own short codes
- Click tracking -- timestamps, referrers, user agents
- QR code generation -- ASCII art QR-style codes in the terminal
- URL validation -- validates format before shortening
- Expiration dates -- set auto-expiry in days
- SQLite backend -- persistent storage, zero setup
- JSON API server -- built-in HTTP server with REST endpoints
- Bulk shortening -- shorten URLs from a file
- Analytics -- top URLs, click trends, daily breakdown
- Import/Export -- full data portability as JSON
- JSON output mode -- machine-readable output for scripting
Just copy url_shortener.py -- zero dependencies required (uses Python standard library only).
git clone https://github.com/Anuar-boop/url-shortener.git
cd url-shortenerpython url_shortener.py shorten https://www.example.com/very/long/path
# Output:
# Shortened: http://localhost:8080/aB3xYz
# Code: aB3xYz
# Original: https://www.example.com/very/long/pathpython url_shortener.py shorten https://example.com --custom mylink
# Shortened: http://localhost:8080/mylinkpython url_shortener.py expand aB3xYz
# https://www.example.com/very/long/pathpython url_shortener.py qr aB3xYzpython url_shortener.py stats aB3xYz
# Short Code: aB3xYz
# Original: https://www.example.com/very/long/path
# Created: 2026-03-04 12:00:00
# Expires: Never
# Clicks: 42python url_shortener.py analytics
# Total URLs: 150
# Total Clicks: 2,340
#
# Top URLs:
# mylink 523 clicks https://example.com
# aB3xYz 342 clicks https://www.example.com/very/long/path
#
# Clicks (last 7 days):
# 2026-03-01 45 #############################################
# 2026-03-02 67 ###################################################################python url_shortener.py bulk urls.txt
# aB3xYz http://localhost:8080/aB3xYz <- https://example.com
# cD4wRt http://localhost:8080/cD4wRt <- https://another.com
# 2/2 shortened.python url_shortener.py serve --port 8080API endpoints:
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/shorten |
Create short URL |
GET |
/api/urls |
List all URLs |
GET |
/api/<code> |
Get URL info + clicks |
GET |
/api/analytics |
Analytics dashboard |
GET |
/<code> |
Redirect to original URL |
Create short URL:
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "custom_code": "mylink"}'# Export all data
python url_shortener.py export -o backup.json
# Import from backup
python url_shortener.py import backup.jsonusage: url-shortener [-h] [--db PATH] [--base-url URL] [--json] [--version]
{shorten,expand,qr,stats,list,analytics,bulk,delete,export,import,serve}
commands:
shorten Shorten a URL
expand Expand a short code to original URL
qr Generate ASCII QR code
stats Show click stats for a URL
list List all shortened URLs
analytics Show overall analytics
bulk Bulk shorten from file
delete Delete a short URL
export Export all data as JSON
import Import data from JSON
serve Start JSON API server
| Option | Description |
|---|---|
--db PATH |
SQLite database file path |
--base-url URL |
Base URL for generated links |
--json |
Output in JSON format |
from url_shortener import URLDatabase, QRCode, validate_url
db = URLDatabase("my_urls.db")
# Shorten
code = db.shorten("https://example.com")
code = db.shorten("https://example.com", custom_code="mylink", expires_in=30)
# Expand
url = db.expand(code)
# Stats
info = db.get_info(code)
clicks = db.get_clicks(code, limit=10)
# Analytics
stats = db.analytics()
# QR Code
qr = QRCode.generate("https://example.com")
print(qr)
db.close()MIT License - see LICENSE for details.