From 85cf9982a2249c350bf81081f132f91cf1d66a92 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 7 Jun 2026 01:52:15 -0400 Subject: [PATCH] Add CI workflow and warm-boot the slow lazy bits GitHub Actions runs pytest on push/PR via uv. App lifespan now loads the g2p model and builds the near-rhyme index at startup so the first keystroke and first lookup are never slow. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 17 +++++++++++++++++ app.py | 15 ++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..56e817d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,17 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - run: uv sync --frozen + - run: uv run pytest diff --git a/app.py b/app.py index 318c9db..99723a3 100644 --- a/app.py +++ b/app.py @@ -9,6 +9,7 @@ Run it: uv run uvicorn app:app --reload import re from collections import defaultdict +from contextlib import asynccontextmanager from functools import lru_cache from pathlib import Path @@ -18,7 +19,19 @@ from fastapi.staticfiles import StaticFiles from pydantic import BaseModel from wordfreq import zipf_frequency -app = FastAPI(title="RhymePad") + +@asynccontextmanager +async def lifespan(app: FastAPI): + # warm the slow lazy bits at boot, not on the first keystroke + try: + g2p_phones("warmup") + except Exception: + pass # model unavailable; spelling fallbacks still work + get_slant_index() + yield + + +app = FastAPI(title="RhymePad", lifespan=lifespan) _g2p = None