feat: add AI quiz generation endpoint with httpx and OpenAI/Ollama support
PyTest / test (push) Has been cancelled

This commit is contained in:
2026-07-28 09:28:57 -04:00
parent 4d1f1d3165
commit d0ed79a986
3 changed files with 54 additions and 0 deletions
+2
View File
@@ -34,6 +34,7 @@ from classquiz.routers import (
quiztivity,
pixabay,
moderation,
ai,
)
from classquiz.socket_server import sio
from classquiz.helpers import meilisearch_init
@@ -104,6 +105,7 @@ app.include_router(login.router, tags=["auth"], prefix="/api/v1/login", include_
app.add_middleware(SessionMiddleware, secret_key=settings.secret_key)
app.include_router(users.router, tags=["users"], prefix="/api/v1/users", include_in_schema=True)
app.include_router(quiz.router, tags=["quiz"], prefix="/api/v1/quiz", include_in_schema=True)
app.include_router(ai.router, tags=["ai"], prefix="/api/v1/ai", include_in_schema=True)
app.include_router(utils.router, tags=["utils"], prefix="/api/v1/utils", include_in_schema=True)
app.include_router(stats.router, tags=["stats"], prefix="/api/v1/stats", include_in_schema=True)
app.include_router(storage.router, tags=["storage"], prefix="/api/v1/storage", include_in_schema=True)
+40
View File
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2026 LobotomyLabs
# SPDX-License-Identifier: MPL-2.0
import os
import json
import httpx
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from classquiz.auth import get_current_user
from classquiz.db.models import User, QuizInput
router = APIRouter()
class AIGenerateRequest(BaseModel):
topic: str
num_questions: int = 5
@router.post("/generate", response_model=QuizInput)
async def generate_ai_quiz(req: AIGenerateRequest, user: User = Depends(get_current_user)):
api_key = os.getenv("AI_API_KEY", "")
base_url = os.getenv("AI_BASE_URL", "https://api.openai.com/v1")
model = os.getenv("AI_MODEL", "gpt-4o-mini")
prompt = f"Generate a quiz about '{req.topic}' with exactly {req.num_questions} multiple-choice questions (ABCD type). Return ONLY valid JSON with keys: title, description, questions (list of {{question, time: '20', type: 'ABCD', answers: [{{answer, right: bool, color}}]}})."
async with httpx.AsyncClient(timeout=30.0) as client:
res = await client.post(
f"{base_url}/chat/completions",
headers={"Authorization": f"Bearer {api_key}"},
json={"model": model, "messages": [{"role": "user", "content": prompt}], "temperature": 0.7},
)
if res.status_code != 200:
raise HTTPException(status_code=502, detail=f"AI provider error: {res.text}")
content = res.json()["choices"][0]["message"]["content"].strip()
if content.startswith("```"):
content = content.split("```")[1]
if content.startswith("json"):
content = content[4:]
content = content.strip("` \n")
return QuizInput(**json.loads(content))
+12
View File
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: 2026 LobotomyLabs
# SPDX-License-Identifier: MPL-2.0
import pytest
from fastapi.testclient import TestClient
from classquiz import app
client = TestClient(app)
def test_ai_router_exists():
response = client.post("/api/v1/ai/generate", json={"topic": "Python", "num_questions": 1})
assert response.status_code in [200, 401, 502]