Skip to content

jannis793/shortpy

Repository files navigation

shortpy

CI License: MIT Python

shortpy is a small, self-hosted URL shortener built with FastAPI and SQLite. It gives you durable short links, HTTP 301 redirects, a clean web UI, OpenAPI docs, rate limiting, Docker support, and click analytics without needing an external service.

shortpy web UI screenshot

Features

  • FastAPI application with automatic OpenAPI docs at /docs
  • SQLite storage with SQLAlchemy models and Alembic migrations
  • Random or custom short codes
  • HTTP 301 redirects
  • Click analytics with timestamp, IP address, user agent, and referer
  • Simple responsive web UI
  • API-first design for automation
  • Rate limiting for link creation
  • Reserved route protection so generated links do not collide with /docs, /api, or static assets
  • Docker and Docker Compose deployment
  • pytest + httpx/FastAPI TestClient coverage
  • GitHub Actions CI for linting and tests

Quick Start

python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
cp .env.example .env
alembic upgrade head
uvicorn shortpy.main:app --reload

Open http://localhost:8000 for the web UI or http://localhost:8000/docs for the API docs.

Docker

docker compose up --build

The Compose setup stores SQLite data in a named Docker volume and exposes the app at http://localhost:8000.

API Examples

Create a short link:

curl -X POST http://localhost:8000/api/links \
  -H "Content-Type: application/json" \
  -d '{"target_url":"https://example.com/a/very/long/path"}'

Create a custom short code:

curl -X POST http://localhost:8000/api/links \
  -H "Content-Type: application/json" \
  -d '{"target_url":"https://example.com/docs","custom_code":"launch"}'

Read analytics:

curl http://localhost:8000/api/links/launch

Redirect:

curl -I http://localhost:8000/launch

Environment Variables

Variable Default Description
SHORTPY_BASE_URL http://localhost:8000 Public base URL used when returning short links.
SHORTPY_DATABASE_URL sqlite:///./shortpy.db SQLAlchemy database URL.
SHORTPY_ENV development Environment label for deployments.
SHORTPY_RATE_LIMIT 30/minute SlowAPI rate limit applied to link creation.
SHORTPY_CODE_LENGTH 7 Generated short code length, from 4 to 16 characters.

Database Migrations

Run migrations locally:

alembic upgrade head

Create a new migration after model changes:

alembic revision --autogenerate -m "describe change"

The app also creates missing tables at startup for lightweight self-hosted deployments. Alembic remains the recommended path for controlled production upgrades.

Development

python -m pip install -e ".[dev]"
ruff check .
alembic upgrade head
pytest --cov=shortpy --cov-report=term-missing

Before opening a pull request, run linting and tests locally and include any behavior changes in the README or tests. CI and Docker builds use constraints.txt to keep dependency resolution reproducible; regenerate it after intentional dependency upgrades.

Project Structure

src/shortpy/
  config.py      Settings from environment variables
  database.py    SQLAlchemy engine and session wiring
  main.py        FastAPI routes, UI, rate limiting, redirects
  models.py      SQLAlchemy models
  schemas.py     Pydantic API schemas
  services.py    Link creation, lookup, and analytics logic

Production Notes

  • Put the app behind HTTPS before exposing it publicly.
  • Set SHORTPY_BASE_URL to the externally reachable origin.
  • Persist the SQLite database file with a host mount or Docker volume.
  • Consider a reverse proxy such as Caddy, Traefik, or nginx for TLS and access logs.
  • For high-write workloads, move from SQLite to PostgreSQL using the same SQLAlchemy model layer.

Contributing

Contributions are welcome. See CONTRIBUTING.md for local setup, testing, and pull request expectations. Changes are tracked in CHANGELOG.md, and dependency updates are monitored through Dependabot.

License

MIT

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors