#!/usr/bin/env bash # Restart the backend: kill the whole uvicorn process tree on port 8000, then start --reload. # Log goes to repo root backend_run.log. # Usage (Git Bash, from repo root): bash backend/restart_backend.sh set -u # Always run relative to this script, so it works from any cwd. cd "$(dirname "$0")" || exit 1 # 1) Kill every python process running THIS backend. uvicorn --reload on Windows # spawns three processes (top launcher -> reloader -> worker); killing only the # port listener leaves an orphan reloader that can later rebind :8000 and fight # the new instance. Match the command line to catch launcher + reloader, then # taskkill /T tears down each of their descendant trees (the worker included). pids=$(wmic process where "name='python.exe' and commandline like '%uvicorn app.main%'" \ get ProcessId 2>/dev/null \ | tr -d '\r' \ | grep -Eo '[0-9]+' \ | sort -u) if [ -n "$pids" ]; then for pid in $pids; do echo "kill old backend PID $pid" # //PID double slash stops Git Bash from turning /PID into a path. taskkill //PID "$pid" //T //F >/dev/null 2>&1 done sleep 2 fi # 2) Clear SSLKEYLOGFILE: the user env var's value has a leading U+202A control # char that makes asyncpg throw OSError [Errno 22] on connect. unset SSLKEYLOGFILE # 3) Start, redirecting to repo root backend_run.log (--reload for hot reload). echo "starting uvicorn, log: ../backend_run.log" exec .venv/Scripts/python.exe -m uvicorn app.main:app --reload --port 8000 > ../backend_run.log 2>&1