Skip to content

v3.0.2

Choose a tag to compare

@github-actions github-actions released this 13 Mar 01:35
· 340 commits to master since this release

Full Changelog: v3.0.1...v3.0.2

What's New in v3.0.0

✨ New Features

Cayenne Ingestion API (recipeparser/api.py)

  • New FastAPI service exposing two endpoints designed for the Project Cayenne mobile app:
    • POST /ingest — full 3-step pipeline: extract recipes from raw text or PDF → refine into structured Cayenne schema → embed with text-embedding-004
    • POST /embed — standalone query vectorisation for semantic search
  • Supabase JWT authentication (HS256 via PyJWT) on all endpoints; unauthenticated requests are rejected with 401
  • URL ingestion reserved (400 Not Yet Implemented) — groundwork laid for Phase 2

Cayenne Refinement Pass (recipeparser/gemini.py)

  • New refine_recipe_for_cayenne() function powered by Gemini 2.5 Flash (upgraded from 2.0 Flash for native thinking support)
  • Produces fully structured CayenneRecipe output:
    • StructuredIngredient list with id, amount, unit, name, fallback_string, converted_amount, converted_unit, is_ai_converted
    • TokenizedDirection list using Fat Token format ({{ing_01|fallback text}}) — ingredient references embedded directly in direction text for deterministic math-scaling
    • AI-powered Volume-to-Weight conversion flagged with is_ai_converted for UI transparency
  • New get_embeddings() using text-embedding-004 (1536-dimensional vectors, compatible with pgvector / sqlite-vec)

Pipeline Resumability (recipeparser/pipeline.py)

  • Checkpoint persistence — pipeline state saved to <output_dir>/.recipeparser_checkpoints/<book_hash>.json after each segment; automatically resumed on re-run of the same book
  • Cooperative pause/resume — PipelineController.check_pause_point() called between segments; race condition between PAUSING → PAUSED and orchestrator check handled correctly
  • FSM correctness fix — transition("done") now called at end of process_epub so the controller correctly reaches IDLE on successful completion
  • Rate-limit auto-pause — PipelineController tracks RPM consumption and automatically pauses + resumes when the Gemini free-tier window resets

🔧 Improvements

  • Gemini 2.5 Flash used for the refinement pass (was 2.0 Flash); native thinking mode improves structured output accuracy
  • Docker smoke test (tests/smoke_test_docker.py) added to CI; validates the containerised API starts and responds correctly
  • Dockerfile dependencies updated to match requirements.txt (FastAPI, Uvicorn, HTTPx, PyJWT)

🧪 Testing

  • 356 tests, 0 failures (up from 350 in v2.2.0)
  • New test modules:
    • tests/test_api.py — 43 tests covering /ingest and /embed endpoints, auth, error paths, schema validation, and UOM passthrough
    • tests/test_gemini_cayenne.py — 4 tests for get_embeddings and refine_recipe_for_cayenne
    • tests/test_gui.py — 6 tests for _parse_run_config logic
    • tests/test_pipeline_resumability.py — 3 integration tests: checkpoint save/load, cancel, and pause/resume
  • Headless GUI test support — conftest.py injects lightweight tkinter / customtkinter stubs when the C extension is unavailable (e.g. CI environments without a display)

🔒 Security

  • API key (GOOGLE_API_KEY) never exposed in responses or logs
  • Supabase JWT secret validated server-side; all ingestion requests require a valid bearer token

📦 New Dependencies

Package Version Purpose
fastapi ≥ 0.115.0 Cayenne Ingestion API
uvicorn ≥ 0.30.0 ASGI server for FastAPI
httpx ≥ 0.27.0 Async HTTP client (test client)
PyJWT ≥ 2.8.0 Supabase JWT verification

🐛 Bug Fixes

  • CI fix — tests/test_api.py now sets DISABLE_AUTH=1 before importing api.py, preventing HTTPBearer(auto_error=True) from rejecting unauthenticated test requests at the middleware layer before dependency_overrides can intercept them

Full Changelog: https://github.com/IanDBallard/RecipeParser/blob/master/CHANGELOG.md