#!/usr/bin/env bash # Start the API for local development. # # Deliberately explicit about two things that have silently gone wrong before: # # 1. The interpreter. Running `uv run` from outside the project directory # resolves to whatever Python is ambient (a pyenv 3.14 in one case), which # started an app missing its routers - /health/live returned 404 while / # served an unrelated page. Anchoring to the project root and calling the # venv's uvicorn directly removes the ambiguity. # # 2. The database. `.env` points DATABASE_URL at production Neon. Running the # API locally against it means local experiments write to production, so # this defaults to a local SQLite file instead. Override with DEV_DB= to # choose something else. # # Usage: # scripts/dev.sh # local SQLite (dev.db) # DEV_DB=sqlite:///./other.db scripts/dev.sh # PORT=5002 scripts/dev.sh set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" if [[ ! -x .venv/bin/uvicorn ]]; then echo "error: .venv/bin/uvicorn not found in $ROOT" >&2 echo " create it with: uv sync" >&2 exit 1 fi DEV_DB="${DEV_DB:-sqlite:///./dev.db}" PORT="${PORT:-5001}" if [[ "$DEV_DB" != sqlite* ]]; then echo "warning: DEV_DB is not SQLite ($DEV_DB) - you may be writing to a shared database" >&2 fi echo "python : $(.venv/bin/python --version)" echo "db : $DEV_DB" echo "port : $PORT" echo exec env DATABASE_URL="$DEV_DB" .venv/bin/uvicorn app.main:app \ --host 127.0.0.1 --port "$PORT" "$@"