refactor main.py and separate concerns - #96
Conversation
📝 WalkthroughWalkthroughThe change extracts LLM configuration, schemas, prompts, provider helpers, and FastAPI routes from ChangesLLM API refactor
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Router
participant LLM
participant Provider
Client->>Router: POST /api/ai/parse
Router->>LLM: Normalize provider and create completion
LLM->>Provider: Send prompt with JSON response settings
Provider-->>LLM: Return model content
LLM-->>Router: Parse JSON content
Router-->>Client: Return GenerateResponse
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
gen-ai/llm.py (1)
20-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSort
__all__to satisfy Ruff RUF022.Ruff flags
__all__as unsorted. Apply isort-style alphabetical ordering.♻️ Proposed fix
__all__ = [ - "OpenAI", - "OpenAIError", - "NO_LLM_NOTE", - "CANNED_INGREDIENTS", - "get_client", - "openai_available", - "normalize_provider", - "create_chat_completion", - "parse_json_content", + "CANNED_INGREDIENTS", + "NO_LLM_NOTE", + "OpenAI", + "OpenAIError", + "create_chat_completion", + "get_client", + "normalize_provider", + "openai_available", + "parse_json_content", ]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gen-ai/llm.py` around lines 20 - 30, Sort the symbols in the module-level __all__ list alphabetically in isort/Ruff RUF022 order, preserving all existing exports.Source: Linters/SAST tools
gen-ai/routers.py (1)
45-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd structured logging on fallback paths.
Errors are silently swallowed and replaced with fallback data. Without logging, production debugging is difficult since the client always receives a 200.
♻️ Suggested addition for both fallback blocks
import logging + +logger = logging.getLogger(__name__)In each except block:
except (OpenAIError, KeyError, TypeError, ValueError): + logger.exception("LLM call failed, returning fallback response") return GenerateResponse(dish=request.dish, ingredients=CANNED_INGREDIENTS, note=NO_LLM_NOTE)Also applies to: 69-72
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gen-ai/routers.py` around lines 45 - 46, Add structured logging to both fallback exception handlers in the relevant router endpoint, including the caught exception and useful request context before returning the canned GenerateResponse; preserve the existing fallback response behavior while ensuring both the handler around lines 45-46 and the additional block around lines 69-72 emit logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@gen-ai/routers.py`:
- Line 3: Replace HTTPException with TypeError in both exception clauses within
the relevant router functions, including the handlers around
normalize_provider/build_system_prompt and
create_chat_completion/parse_json_content/Ingredient construction, and remove
the now-unused HTTPException import from fastapi.
---
Nitpick comments:
In `@gen-ai/llm.py`:
- Around line 20-30: Sort the symbols in the module-level __all__ list
alphabetically in isort/Ruff RUF022 order, preserving all existing exports.
In `@gen-ai/routers.py`:
- Around line 45-46: Add structured logging to both fallback exception handlers
in the relevant router endpoint, including the caught exception and useful
request context before returning the canned GenerateResponse; preserve the
existing fallback response behavior while ensuring both the handler around lines
45-46 and the additional block around lines 69-72 emit logs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b98d8881-3824-4805-ba5a-5b0b0997291f
📒 Files selected for processing (13)
gen-ai/config.pygen-ai/llm.pygen-ai/main.pygen-ai/prompts.pygen-ai/pytest.inigen-ai/routers.pygen-ai/schemas.pygen-ai/tests/conftest.pygen-ai/tests/test_endpoint_merge.pygen-ai/tests/test_endpoint_parse.pygen-ai/tests/test_parse_json_content.pygen-ai/tests/test_prompts.pygen-ai/tests/test_provider.py
| @@ -0,0 +1,74 @@ | |||
| import json | |||
|
|
|||
| from fastapi import APIRouter, HTTPException | |||
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
HTTPException is caught but never raised; TypeError is missing from the except clause.
None of the functions called in the try blocks (normalize_provider, build_system_prompt, create_chat_completion, parse_json_content, Ingredient(**item)) raise HTTPException. Conversely, if the LLM returns a non-dict structure (e.g., a top-level JSON array or {"ingredients": [1, 2, 3]}), data["ingredients"] or Ingredient(**item) will raise TypeError, which is not caught and will produce a 500 instead of falling back.
🛡️ Proposed fix: replace HTTPException with TypeError and remove unused import
-from fastapi import APIRouter, HTTPException
+from fastapi import APIRouterApply to both except clauses (lines 45 and 69):
- except (HTTPException, OpenAIError, KeyError, ValueError):
+ except (OpenAIError, KeyError, TypeError, ValueError):Also applies to: 45-45, 69-69
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@gen-ai/routers.py` at line 3, Replace HTTPException with TypeError in both
exception clauses within the relevant router functions, including the handlers
around normalize_provider/build_system_prompt and
create_chat_completion/parse_json_content/Ingredient construction, and remove
the now-unused HTTPException import from fastapi.
Closes #89
gen-ai/main.pyhad grown into a single 312-line file mixing five unrelated concerns. This splits it into focused, single-responsibility modules with a clean acyclic dependency graph, no behavior or HTTP contract changes.main.pyconfig.pyload_dotenv(),Providertypeschemas.pyprompts.pyDIETARY_RULES,build_system_promptllm.pyrouters.pyAPIRouterfor/health,/api/ai/parse,/api/ai/mergeSummary by CodeRabbit
New Features
Bug Fixes
Tests