A FastAPI API that receives real API error data and uses an LLM to return a structured diagnosis with likely causes and suggested fixes.
fastapi: async web frameworkuvicorn: ASGI serverhttpx: useful dependency for async HTTP ecosystem workpython-dotenv: environment variable loadingopenai: OpenAI-compatible client (works with OpenAI, Groq, and other compatible providers)pydantic(included by FastAPI): strict input/output validation
app/
main.py # FastAPI app + router wiring + validation handler
core/
config.py # Centralized environment configuration
routers/
health.py # Health check endpoint (/health)
error_analysis.py # HTTP endpoint (/analyze-error)
services/
llm_analyzer.py # LLM logic and JSON parsing/validation
schemas/
error_analysis.py # Request/response models (Pydantic)
Applied principle:
- Routers only orchestrate HTTP concerns.
- Services contain business/LLM logic.
- Schemas define input/output contracts.
- Create a virtual environment and install dependencies:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt- Configure environment variables:
cp .env.example .envVariables:
LLM_PROVIDER:openaiorgroqLLM_TIMEOUT_SECONDS: LLM call timeoutOPENAI_API_KEY,OPENAI_BASE_URL,OPENAI_MODELGROQ_API_KEY,GROQ_BASE_URL,GROQ_MODEL
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-miniLLM_PROVIDER=groq
GROQ_API_KEY=gsk_...
GROQ_BASE_URL=https://api.groq.com/openai/v1
GROQ_MODEL=llama-3.1-8b-instantThe app uses an OpenAI-compatible client and selects the provider from app/core/config.py, so you can switch between OpenAI and Groq by changing only environment variables.
Common options:
- Groq (often has a free tier):
GROQ_BASE_URL=https://api.groq.com/openai/v1 - OpenRouter (depends on model and plan)
- OpenAI (usually requires billing)
uvicorn app.main:app --reloadSwagger UI:
Response body:
{
"status": "ok",
"service": "ai-api-debugger"
}Request body:
{
"api_url": "https://api.example.com/v1/users",
"method": "GET",
"status_code": 401,
"error_message": "Invalid OAuth token",
"context": "Token generated 2 hours ago with read scope only"
}Response body:
{
"diagnosis": "OAuth token is invalid or expired for this endpoint.",
"possible_causes": [
"Access token expired",
"Token audience does not match API",
"Missing required OAuth scope"
],
"suggested_fix": "Regenerate the token with correct audience and scopes, then retry with a valid Bearer token."
}- A
system promptenforces API-debugging-expert behavior. - JSON output is forced with
response_format={"type":"json_object"}. - Content is parsed with
json.loads. - Final output is validated with
ErrorAnalysisResponse(Pydantic), preventing invalid formats.
Covered errors:
- Invalid HTTP payload ->
422 ValidationError - Invalid JSON returned by LLM ->
502 InvalidLLMResponse - LLM provider failure / timeout / missing API key ->
503 LLMServiceUnavailable
Clean error example:
{
"detail": {
"error": "InvalidLLMResponse",
"message": "LLM returned invalid JSON."
}
}- End-to-end async/await implementation.
- Layer separation (router/service/schema).
- Request and response validation via Pydantic.
- Explicit handling of infrastructure and parsing exceptions.
- Client sends API error data to
POST /analyze-error. - Router validates input and delegates to the service.
- Service builds a structured prompt and calls the LLM.
- JSON is parsed and validated against schema.
- API returns consistent, typed diagnostics.