Skip to content

ablott976/splitbill-oss

Repository files navigation

SplitBill

Open-source web app for splitting restaurant bills in real time. Upload a receipt, extract line items with OCR, share a link/QR with the group, and let each participant claim items and mark their share as paid.

Features

  • Receipt OCR for JPEG/PNG uploads using Google Gemini.
  • Shared ticket URLs valid for short-lived group sessions.
  • Real-time updates with WebSockets plus Redis pub/sub for multi-worker deployments.
  • Item claiming, item sharing, manual item editing/deletion and cent-level rounding.
  • Tip calculation and per-person payment tracking.
  • Browser-local ticket history and reusable participant groups.
  • Multilingual UI: Spanish, English, Portuguese and Catalan.

Security posture

This repository is designed to be safe to publish as OSS:

  • No real API keys, database passwords or admin secrets are committed.
  • SECRET_KEY has no application default; admin cleanup is disabled until configured.
  • Production mode validates strong secrets, explicit trusted hosts and non-wildcard CORS.
  • Uploads are restricted to JPEG/PNG and size-limited with MAX_UPLOAD_BYTES (default 5 MiB).
  • OCR calls use the uploaded file MIME type and run off the FastAPI event loop.
  • User-controlled names in delete confirmations are rendered as text, not HTML.

Anyone with a ticket URL can collaboratively edit that ticket. Treat ticket links as bearer links and do not use the app for sensitive financial records.

Requirements

  • Python 3.12+
  • PostgreSQL
  • Redis
  • Google Gemini API key for OCR (GEMINI_API_KEY)

Local setup

git clone https://github.com/ablott976/splitbill-oss.git
cd splitbill-oss
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# edit .env and set SECRET_KEY / database / Redis / optional GEMINI_API_KEY
uvicorn app.main:app --reload

Open http://localhost:8000.

Generate a local secret with:

openssl rand -base64 32

Docker Compose

cp .env.example .env
# edit SECRET_KEY and POSTGRES_PASSWORD
cd docker
docker compose up --build

Health check:

curl http://localhost:8000/health

Environment variables

  • ENVIRONMENT: development or production.
  • DATABASE_URL: async SQLAlchemy PostgreSQL URL.
  • REDIS_URL: Redis URL for pub/sub.
  • SECRET_KEY: admin cleanup secret; required for cleanup and validated in production.
  • GEMINI_API_KEY: optional at startup, required for OCR.
  • ALLOWED_ORIGINS: comma-separated CORS origins. Wildcard is rejected in production.
  • TRUSTED_HOSTS: comma-separated hostnames accepted by TrustedHostMiddleware. Wildcard is rejected in production.
  • MAX_UPLOAD_BYTES: upload limit in bytes, default 5 MiB.

Tests

pip install -r requirements.txt
pytest -q

API overview

  • POST /api/tickets — create a ticket.
  • GET /api/tickets/{token} — fetch current ticket state.
  • POST /api/tickets/{token}/image — upload receipt image for OCR.
  • POST /api/tickets/{token}/upload — HTMX upload endpoint.
  • PATCH /api/tickets/{token}/tip — update tip percentage.
  • POST /api/tickets/{token}/items — add an item.
  • PUT /api/tickets/{token}/items/{item_id} — edit an item.
  • DELETE /api/tickets/{token}/items/{item_id} — delete an item.
  • POST /api/admin/cleanup — cleanup expired tickets, protected by X-Secret-Key.
  • GET /health — health check.
  • WS /ws/{token} — real-time ticket updates.

License

MIT

About

Open-source real-time restaurant bill splitting app with OCR

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors