Soacti commited on
Commit
6e5d7fd
·
verified ·
1 Parent(s): 1078d41

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +277 -196
app.py CHANGED
@@ -4,9 +4,7 @@ import time
4
  import os
5
  from typing import List, Dict, Any, Optional
6
  import random
7
-
8
- # Import Hugging Face inference API
9
- from huggingface_hub import InferenceClient
10
 
11
  # API key validation
12
  def validate_api_key(api_key: str) -> bool:
@@ -17,199 +15,269 @@ def validate_api_key(api_key: str) -> bool:
17
  return False
18
  return api_key == expected_key
19
 
20
- # AI Quiz generation with Hugging Face models
21
  class AIQuizGenerator:
22
  def __init__(self):
23
  self.api_key = os.environ.get("HUGGINGFACE_API_KEY")
24
- if not self.api_key:
25
- print("WARNING: HUGGINGFACE_API_KEY not set in environment variables")
26
 
27
- # Use a more capable model for better quiz generation
28
- self.default_model = "microsoft/DialoGPT-medium"
29
- self.fallback_model = "google/flan-t5-base"
 
 
 
 
30
 
31
- # Initialize the client
32
- self.client = InferenceClient(token=self.api_key) if self.api_key else None
33
 
34
  def generate_quiz(self, tema: str, antall: int = 3, språk: str = "no") -> List[Dict[str, Any]]:
35
- """Generate quiz questions using AI - NO RESTRICTIONS ON TOPIC"""
36
- if not self.client:
37
- print("No Hugging Face API key available, generating basic questions")
38
- return self._generate_basic_questions(tema, antall)
39
-
40
- try:
41
- # Build flexible prompt that works with ANY topic
42
- prompt = self._build_flexible_prompt(tema, antall, språk)
43
-
44
- # Try primary model first
45
- start_time = time.time()
46
  try:
47
- response = self.client.text_generation(
48
- prompt,
49
- model=self.default_model,
50
- max_new_tokens=1500,
51
- temperature=0.8,
52
- repetition_penalty=1.1,
53
- do_sample=True
54
- )
55
- except:
56
- # Fallback to more reliable model
57
- response = self.client.text_generation(
58
- prompt,
59
- model=self.fallback_model,
60
- max_new_tokens=1200,
61
- temperature=0.7,
62
- repetition_penalty=1.2,
63
- )
64
-
65
- generation_time = time.time() - start_time
66
-
67
- print(f"AI response received in {generation_time:.2f}s for topic: {tema}")
68
- print(f"Response preview: {response[:300]}...")
69
-
70
- # Parse the response into questions
71
- questions = self._parse_flexible_response(response, tema, antall)
72
-
73
- # If we couldn't parse enough questions, generate more basic ones
74
- if len(questions) < antall:
75
- additional = self._generate_basic_questions(tema, antall - len(questions))
76
- questions.extend(additional)
77
-
78
- return questions[:antall]
79
-
80
- except Exception as e:
81
- print(f"Error generating quiz with AI: {str(e)}")
82
- return self._generate_basic_questions(tema, antall)
83
 
84
- def _build_flexible_prompt(self, tema: str, antall: int, språk: str) -> str:
85
- """Build a flexible prompt that works with ANY topic"""
86
- language = "norsk" if språk == "no" else "English"
87
 
88
- return f"""Create {antall} quiz questions about "{tema}" in {language}.
89
-
90
- IMPORTANT: Generate questions about ANY topic the user requests - there are NO restrictions.
91
- Whether it's about science, history, pop culture, technology, sports, entertainment, food, travel, or anything else - create relevant questions.
92
-
93
- Format each question EXACTLY like this:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- Q1: [Clear question about {tema}]
96
- A) [First option]
97
- B) [Second option]
98
- C) [Third option]
99
- D) [Fourth option]
100
- CORRECT: [A, B, C, or D]
101
- EXPLANATION: [Brief explanation why this is correct]
 
102
 
103
- Q2: [Second question about {tema}]
104
- A) [First option]
105
- B) [Second option]
106
- C) [Third option]
107
- D) [Fourth option]
108
- CORRECT: [A, B, C, or D]
109
- EXPLANATION: [Brief explanation]
 
110
 
111
- Continue for all {antall} questions about "{tema}".
 
 
112
 
113
- Make the questions interesting and educational. Use your knowledge to create accurate, relevant questions about this topic.
 
 
 
 
 
 
 
114
 
115
- Topic: {tema}
116
- Generate {antall} questions now:
117
- """
118
 
119
- def _parse_flexible_response(self, response: str, tema: str, expected_count: int) -> List[Dict[str, Any]]:
120
- """Parse AI response with flexible parsing for any topic"""
121
  questions = []
122
 
123
- # Split response into potential question blocks
124
- lines = response.split('\n')
125
- current_question = {}
126
- current_options = []
127
 
128
- for line in lines:
129
- line = line.strip()
130
- if not line:
 
 
 
 
131
  continue
132
-
133
- # Look for question patterns
134
- if line.startswith(('Q1:', 'Q2:', 'Q3:', 'Q4:', 'Q5:')) or 'SPØRSMÅL:' in line.upper():
135
- # Save previous question if complete
136
- if self._is_complete_question(current_question, current_options):
137
- current_question["alternativer"] = current_options
138
- questions.append(current_question)
139
-
140
- # Start new question
141
- question_text = line.split(':', 1)[1].strip() if ':' in line else line
142
- current_question = {"spørsmål": question_text}
143
- current_options = []
144
-
145
- elif line.startswith(('A)', 'B)', 'C)', 'D)')):
146
- option = line[2:].strip()
147
- if option:
148
- current_options.append(option)
149
-
150
- elif 'CORRECT:' in line.upper() or 'KORREKT:' in line.upper():
151
- correct_part = line.upper().split('CORRECT:')[-1].split('KORREKT:')[-1].strip()
152
- if correct_part and correct_part[0] in ['A', 'B', 'C', 'D']:
153
- current_question["korrekt_svar"] = ['A', 'B', 'C', 'D'].index(correct_part[0])
154
-
155
- elif 'EXPLANATION:' in line.upper() or 'FORKLARING:' in line.upper():
156
- explanation = line.split(':')[1].strip() if ':' in line else line
157
- current_question["forklaring"] = explanation
158
-
159
- # Add the last question if complete
160
- if self._is_complete_question(current_question, current_options):
161
- current_question["alternativer"] = current_options
162
- questions.append(current_question)
163
-
164
- return questions
165
 
166
- def _is_complete_question(self, question: Dict, options: List) -> bool:
167
- """Check if a question is complete"""
168
- return (
169
- "spørsmål" in question and
170
- len(options) >= 3 and # At least 3 options
171
- "korrekt_svar" in question and
172
- question["korrekt_svar"] < len(options)
173
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
- def _generate_basic_questions(self, tema: str, antall: int) -> List[Dict[str, Any]]:
176
- """Generate basic questions when AI fails - works with ANY topic"""
 
 
 
177
  questions = []
178
 
179
- # Generate generic but relevant questions for any topic
180
- question_templates = [
181
- f"Hva er det mest kjente ved {tema}?",
182
- f"Hvilket år er viktig i historien til {tema}?",
183
- f"Hvor finner man vanligvis {tema}?",
184
- f"Hva karakteriserer {tema}?",
185
- f"Hvilken betydning har {tema}?"
186
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
- for i in range(min(antall, len(question_templates))):
189
- questions.append({
190
- "spørsmål": question_templates[i],
191
- "alternativer": [
192
- f"Alternativ A om {tema}",
193
- f"Alternativ B om {tema}",
194
- f"Alternativ C om {tema}",
195
- f"Alternativ D om {tema}"
196
- ],
197
- "korrekt_svar": 0, # Always A for simplicity
198
- "forklaring": f"Dette er et generert spørsmål om {tema}. For mer nøyaktige spørsmål, prøv igjen - AI-systemet lærer kontinuerlig."
199
- })
200
-
201
- return questions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  # Initialize the AI generator
204
  quiz_generator = AIQuizGenerator()
205
 
206
- # API endpoint for quiz generation - NO TOPIC RESTRICTIONS
207
  def generate_quiz_api(tema: str, språk: str = "no", antall_spørsmål: int = 3,
208
  type: str = "sted", vanskelighetsgrad: int = 3,
209
  api_key: str = None) -> Dict[str, Any]:
210
- """API endpoint for quiz generation - ACCEPTS ANY TOPIC"""
211
 
212
- # Validate API key
213
  if not validate_api_key(api_key):
214
  return {
215
  "success": False,
@@ -217,7 +285,6 @@ def generate_quiz_api(tema: str, språk: str = "no", antall_spørsmål: int = 3,
217
  "questions": []
218
  }
219
 
220
- # NO TOPIC FILTERING - Accept absolutely anything
221
  if not tema or len(tema.strip()) < 2:
222
  return {
223
  "success": False,
@@ -226,21 +293,26 @@ def generate_quiz_api(tema: str, språk: str = "no", antall_spørsmål: int = 3,
226
  }
227
 
228
  try:
229
- # Generate questions with AI - NO RESTRICTIONS
230
  start_time = time.time()
231
  questions = quiz_generator.generate_quiz(tema.strip(), antall_spørsmål, språk)
232
- generation_time = time.time() - start_time
 
 
 
 
233
 
234
  return {
235
  "success": True,
236
  "questions": questions,
237
  "metadata": {
238
- "generation_time": round(generation_time, 2),
239
- "model_used": quiz_generator.default_model,
240
  "topic": tema,
241
- "unrestricted": True # Flag to show no restrictions
 
242
  },
243
- "message": f"Genererte {len(questions)} spørsmål om '{tema}' - ingen begrensninger!"
 
244
  }
245
  except Exception as e:
246
  print(f"Error in generate_quiz_api: {str(e)}")
@@ -250,9 +322,9 @@ def generate_quiz_api(tema: str, språk: str = "no", antall_spørsmål: int = 3,
250
  "questions": []
251
  }
252
 
253
- # Gradio interface - emphasize NO RESTRICTIONS
254
  def generate_quiz_gradio(tema, antall, api_key=None):
255
- """Gradio wrapper - accepts ANY topic"""
256
  if api_key and not validate_api_key(api_key):
257
  return "❌ **Ugyldig API-nøkkel**"
258
 
@@ -266,13 +338,20 @@ def generate_quiz_gradio(tema, antall, api_key=None):
266
  return f"❌ **Feil:** {result['message']}"
267
 
268
  questions = result["questions"]
269
- model = result["metadata"]["model_used"]
270
- time_taken = result["metadata"]["generation_time"]
 
 
 
 
 
 
 
271
 
272
  output = f"✅ **Genererte {len(questions)} spørsmål om '{tema}'**\n\n"
273
- output += f"🤖 **Modell:** {model}\n"
274
- output += f"⏱️ **Tid:** {time_taken}s\n"
275
- output += f"🔓 **Ingen begrensninger** - alle temaer er tillatt!\n\n"
276
 
277
  for i, q in enumerate(questions, 1):
278
  output += f"📝 **Spørsmål {i}:** {q['spørsmål']}\n"
@@ -286,21 +365,25 @@ def generate_quiz_gradio(tema, antall, api_key=None):
286
  except Exception as e:
287
  return f"❌ **Feil:** {str(e)}"
288
 
289
- # Health check endpoint
290
  def health_check():
291
- return {"status": "healthy", "timestamp": time.time(), "unrestricted": True}
 
 
 
 
292
 
293
- # Gradio interface - emphasize freedom
294
- with gr.Blocks(title="SoActi AI Quiz API - Ubegrenset") as demo:
295
- gr.Markdown("# 🧠 SoActi AI Quiz API - Ubegrenset")
296
- gr.Markdown("**🔓 Lag quiz om ABSOLUTT HVASOM HELST - ingen begrensninger!**")
297
 
298
  with gr.Row():
299
  with gr.Column():
300
  tema_input = gr.Textbox(
301
- label="Tema (skriv hva som helst!)",
302
- value="",
303
- placeholder="Fotball, Harry Potter, Kvantfysikk, Baking, TikTok, Dinosaurer, Programmering, K-pop, Filosofi, Gaming..."
304
  )
305
  antall_input = gr.Slider(
306
  minimum=1,
@@ -310,18 +393,18 @@ with gr.Blocks(title="SoActi AI Quiz API - Ubegrenset") as demo:
310
  value=3
311
  )
312
  api_key_input = gr.Textbox(
313
- label="API-nøkkel (for testing)",
314
  placeholder="Skriv inn API-nøkkel...",
315
  type="password"
316
  )
317
 
318
- generate_btn = gr.Button("🚀 Generer Quiz om HVASOM HELST!", variant="primary")
319
 
320
  with gr.Column():
321
  output = gr.Textbox(
322
  label="Generert Quiz",
323
  lines=20,
324
- placeholder="Skriv inn HVILKET SOM HELST tema og klikk 'Generer Quiz'!\n\nEksempler:\n- Marvel filmer\n- Norsk rap\n- Kryptovaluta\n- Yoga\n- Sushi\n- Elon Musk\n- Klimaendringer\n- Netflix serier\n- Fotografi\n- Skateboard"
325
  )
326
 
327
  generate_btn.click(
@@ -330,16 +413,15 @@ with gr.Blocks(title="SoActi AI Quiz API - Ubegrenset") as demo:
330
  outputs=output
331
  )
332
 
333
- gr.Markdown("## 🔗 API for SoActi")
334
  gr.Markdown("`POST https://Soacti-soacti-ai-quiz-api.hf.space/generate-quiz`")
335
- gr.Markdown("**🔓 Ingen begrensninger - brukere kan spørre om hva som helst!**")
336
 
337
- # FastAPI setup with CORS for unrestricted access
338
  from fastapi import FastAPI, HTTPException, Depends, Header
339
  from fastapi.middleware.cors import CORSMiddleware
340
  from pydantic import BaseModel
341
 
342
- app = FastAPI(title="SoActi Quiz API - Ubegrenset")
343
 
344
  app.add_middleware(
345
  CORSMiddleware,
@@ -350,7 +432,7 @@ app.add_middleware(
350
  )
351
 
352
  class QuizRequest(BaseModel):
353
- tema: str # NO restrictions on what this can be
354
  språk: str = "no"
355
  antall_spørsmål: int = 3
356
  type: str = "sted"
@@ -368,9 +450,8 @@ async def get_api_key(authorization: str = Header(None)):
368
 
369
  @app.post("/generate-quiz")
370
  async def api_generate_quiz(request: QuizRequest, api_key: str = Depends(get_api_key)):
371
- """Generate quiz about ANY topic - no restrictions"""
372
  result = generate_quiz_api(
373
- request.tema, # Accept ANY topic
374
  request.språk,
375
  request.antall_spørsmål,
376
  request.type,
 
4
  import os
5
  from typing import List, Dict, Any, Optional
6
  import random
7
+ import requests
 
 
8
 
9
  # API key validation
10
  def validate_api_key(api_key: str) -> bool:
 
15
  return False
16
  return api_key == expected_key
17
 
18
+ # Improved AI Quiz generation
19
  class AIQuizGenerator:
20
  def __init__(self):
21
  self.api_key = os.environ.get("HUGGINGFACE_API_KEY")
22
+ self.api_url = "https://api-inference.huggingface.co/models/microsoft/DialoGPT-large"
 
23
 
24
+ # Backup models to try
25
+ self.models = [
26
+ "microsoft/DialoGPT-large",
27
+ "google/flan-t5-large",
28
+ "facebook/blenderbot-400M-distill",
29
+ "microsoft/DialoGPT-medium"
30
+ ]
31
 
32
+ print(f"AI Generator initialized. API key available: {bool(self.api_key)}")
 
33
 
34
  def generate_quiz(self, tema: str, antall: int = 3, språk: str = "no") -> List[Dict[str, Any]]:
35
+ """Generate quiz questions using Hugging Face Inference API"""
36
+
37
+ if not self.api_key:
38
+ print("❌ No Hugging Face API key - using enhanced fallback")
39
+ return self._generate_enhanced_fallback(tema, antall)
40
+
41
+ # Try multiple models until one works
42
+ for model in self.models:
 
 
 
43
  try:
44
+ print(f"🤖 Trying model: {model}")
45
+ questions = self._try_model(model, tema, antall, språk)
46
+ if questions and len(questions) > 0:
47
+ print(f"✅ Success with model: {model}")
48
+ return questions
49
+
50
+ except Exception as e:
51
+ print(f"❌ Model {model} failed: {str(e)}")
52
+ continue
53
+
54
+ print("❌ All AI models failed - using enhanced fallback")
55
+ return self._generate_enhanced_fallback(tema, antall)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ def _try_model(self, model: str, tema: str, antall: int, språk: str) -> List[Dict[str, Any]]:
58
+ """Try a specific model"""
 
59
 
60
+ # Create a very specific prompt
61
+ prompt = self._create_specific_prompt(tema, antall, språk)
62
+
63
+ headers = {
64
+ "Authorization": f"Bearer {self.api_key}",
65
+ "Content-Type": "application/json"
66
+ }
67
+
68
+ payload = {
69
+ "inputs": prompt,
70
+ "parameters": {
71
+ "max_new_tokens": 800,
72
+ "temperature": 0.7,
73
+ "do_sample": True,
74
+ "top_p": 0.9
75
+ }
76
+ }
77
+
78
+ api_url = f"https://api-inference.huggingface.co/models/{model}"
79
+
80
+ start_time = time.time()
81
+ response = requests.post(api_url, headers=headers, json=payload, timeout=30)
82
+ generation_time = time.time() - start_time
83
+
84
+ print(f"API Response Status: {response.status_code}")
85
+
86
+ if response.status_code != 200:
87
+ raise Exception(f"API returned {response.status_code}: {response.text}")
88
+
89
+ result = response.json()
90
+
91
+ if isinstance(result, list) and len(result) > 0:
92
+ generated_text = result[0].get("generated_text", "")
93
+ else:
94
+ generated_text = str(result)
95
+
96
+ print(f"Generated text preview: {generated_text[:200]}...")
97
+
98
+ # Parse the response
99
+ questions = self._parse_ai_response(generated_text, tema, antall)
100
+
101
+ # Add metadata
102
+ for q in questions:
103
+ q["_metadata"] = {
104
+ "model": model,
105
+ "generation_time": generation_time,
106
+ "ai_generated": True
107
+ }
108
+
109
+ return questions
110
+
111
+ def _create_specific_prompt(self, tema: str, antall: int, språk: str) -> str:
112
+ """Create a very specific prompt for better results"""
113
+
114
+ if språk == "no":
115
+ return f"""Lag {antall} quiz-spørsmål om {tema} på norsk.
116
 
117
+ Format:
118
+ SPØRSMÅL: [konkret spørsmål om {tema}]
119
+ A) [første alternativ]
120
+ B) [andre alternativ]
121
+ C) [tredje alternativ]
122
+ D) [fjerde alternativ]
123
+ SVAR: [A, B, C eller D]
124
+ FORKLARING: [kort forklaring]
125
 
126
+ Eksempel om fotball:
127
+ SPØRSMÅL: Hvem vant Ballon d'Or i 2023?
128
+ A) Lionel Messi
129
+ B) Erling Haaland
130
+ C) Kylian Mbappé
131
+ D) Karim Benzema
132
+ SVAR: A
133
+ FORKLARING: Lionel Messi vant sin åttende Ballon d'Or i 2023.
134
 
135
+ lag {antall} spørsmål om {tema}:"""
136
+ else:
137
+ return f"""Create {antall} quiz questions about {tema} in English.
138
 
139
+ Format:
140
+ QUESTION: [specific question about {tema}]
141
+ A) [first option]
142
+ B) [second option]
143
+ C) [third option]
144
+ D) [fourth option]
145
+ ANSWER: [A, B, C or D]
146
+ EXPLANATION: [brief explanation]
147
 
148
+ Now create {antall} questions about {tema}:"""
 
 
149
 
150
+ def _parse_ai_response(self, text: str, tema: str, expected_count: int) -> List[Dict[str, Any]]:
151
+ """Parse AI response into structured questions"""
152
  questions = []
153
 
154
+ # Split into sections
155
+ sections = text.split("SPØRSMÅL:") if "SPØRSMÅL:" in text else text.split("QUESTION:")
 
 
156
 
157
+ for section in sections[1:]: # Skip first empty section
158
+ try:
159
+ question = self._parse_single_question(section, tema)
160
+ if question:
161
+ questions.append(question)
162
+ except Exception as e:
163
+ print(f"Error parsing question section: {e}")
164
  continue
165
+
166
+ return questions[:expected_count]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
+ def _parse_single_question(self, section: str, tema: str) -> Optional[Dict[str, Any]]:
169
+ """Parse a single question from text"""
170
+ lines = [line.strip() for line in section.split('\n') if line.strip()]
171
+
172
+ if not lines:
173
+ return None
174
+
175
+ question_text = lines[0].strip()
176
+ options = []
177
+ correct_answer = 0
178
+ explanation = ""
179
+
180
+ for line in lines[1:]:
181
+ if line.startswith(('A)', 'B)', 'C)', 'D)')):
182
+ options.append(line[2:].strip())
183
+ elif line.startswith(('SVAR:', 'ANSWER:')):
184
+ answer_part = line.split(':', 1)[1].strip()
185
+ if answer_part in ['A', 'B', 'C', 'D']:
186
+ correct_answer = ['A', 'B', 'C', 'D'].index(answer_part)
187
+ elif line.startswith(('FORKLARING:', 'EXPLANATION:')):
188
+ explanation = line.split(':', 1)[1].strip()
189
+
190
+ if len(options) >= 3 and question_text:
191
+ # Ensure we have 4 options
192
+ while len(options) < 4:
193
+ options.append(f"Alternativ {len(options) + 1}")
194
+
195
+ return {
196
+ "spørsmål": question_text,
197
+ "alternativer": options[:4],
198
+ "korrekt_svar": correct_answer,
199
+ "forklaring": explanation or f"Spørsmål om {tema}"
200
+ }
201
+
202
+ return None
203
 
204
+ def _generate_enhanced_fallback(self, tema: str, antall: int) -> List[Dict[str, Any]]:
205
+ """Generate better fallback questions based on topic analysis"""
206
+
207
+ # Analyze topic to create better questions
208
+ tema_lower = tema.lower()
209
  questions = []
210
 
211
+ # Football/Soccer specific
212
+ if any(word in tema_lower for word in ['fotball', 'football', 'soccer', 'messi', 'ronaldo', 'haaland']):
213
+ questions = [
214
+ {
215
+ "spørsmål": "Hvem regnes som en av verdens beste fotballspillere gjennom tidene?",
216
+ "alternativer": ["Lionel Messi", "Michael Jordan", "Tiger Woods", "Usain Bolt"],
217
+ "korrekt_svar": 0,
218
+ "forklaring": "Lionel Messi regnes som en av de beste fotballspillerne noensinne med 8 Ballon d'Or-priser."
219
+ },
220
+ {
221
+ "spørsmål": "Hvilket land har vunnet flest VM i fotball?",
222
+ "alternativer": ["Tyskland", "Argentina", "Brasil", "Frankrike"],
223
+ "korrekt_svar": 2,
224
+ "forklaring": "Brasil har vunnet VM i fotball 5 ganger (1958, 1962, 1970, 1994, 2002)."
225
+ },
226
+ {
227
+ "spørsmål": "Hva kalles den prestisjetunge individuelle prisen i fotball?",
228
+ "alternativer": ["Golden Boot", "Ballon d'Or", "FIFA Award", "Champions Trophy"],
229
+ "korrekt_svar": 1,
230
+ "forklaring": "Ballon d'Or er den mest prestisjetunge individuelle prisen i fotball."
231
+ }
232
+ ]
233
 
234
+ # Technology specific
235
+ elif any(word in tema_lower for word in ['teknologi', 'technology', 'ai', 'computer', 'programming']):
236
+ questions = [
237
+ {
238
+ "spørsmål": f"Hva er en viktig utvikling innen {tema}?",
239
+ "alternativer": ["Kunstig intelligens", "Dampmaskin", "Hjulet", "Ild"],
240
+ "korrekt_svar": 0,
241
+ "forklaring": f"Kunstig intelligens er en av de viktigste utviklingene innen moderne {tema}."
242
+ }
243
+ ]
244
+
245
+ # Generic but better questions
246
+ if not questions:
247
+ questions = [
248
+ {
249
+ "spørsmål": f"Hva er karakteristisk for {tema}?",
250
+ "alternativer": [f"Viktig egenskap ved {tema}", "Irrelevant faktor", "Tilfeldig element", "Ukjent aspekt"],
251
+ "korrekt_svar": 0,
252
+ "forklaring": f"Dette spørsmålet handler om de karakteristiske egenskapene ved {tema}."
253
+ },
254
+ {
255
+ "spørsmål": f"Hvor er {tema} mest relevant?",
256
+ "alternativer": ["I relevant kontekst", "I irrelevant sammenheng", "Ingen steder", "Overalt"],
257
+ "korrekt_svar": 0,
258
+ "forklaring": f"{tema} er mest relevant i sin naturlige kontekst."
259
+ }
260
+ ]
261
+
262
+ # Add metadata to show these are fallbacks
263
+ for q in questions:
264
+ q["_metadata"] = {
265
+ "model": "enhanced_fallback",
266
+ "generation_time": 0.1,
267
+ "ai_generated": False
268
+ }
269
+
270
+ return questions[:antall]
271
 
272
  # Initialize the AI generator
273
  quiz_generator = AIQuizGenerator()
274
 
275
+ # API endpoint for quiz generation
276
  def generate_quiz_api(tema: str, språk: str = "no", antall_spørsmål: int = 3,
277
  type: str = "sted", vanskelighetsgrad: int = 3,
278
  api_key: str = None) -> Dict[str, Any]:
279
+ """API endpoint for quiz generation"""
280
 
 
281
  if not validate_api_key(api_key):
282
  return {
283
  "success": False,
 
285
  "questions": []
286
  }
287
 
 
288
  if not tema or len(tema.strip()) < 2:
289
  return {
290
  "success": False,
 
293
  }
294
 
295
  try:
 
296
  start_time = time.time()
297
  questions = quiz_generator.generate_quiz(tema.strip(), antall_spørsmål, språk)
298
+ total_time = time.time() - start_time
299
+
300
+ # Check if we got real AI questions or fallbacks
301
+ ai_generated = any(q.get("_metadata", {}).get("ai_generated", False) for q in questions)
302
+ model_used = questions[0].get("_metadata", {}).get("model", "unknown") if questions else "none"
303
 
304
  return {
305
  "success": True,
306
  "questions": questions,
307
  "metadata": {
308
+ "generation_time": round(total_time, 2),
309
+ "model_used": model_used,
310
  "topic": tema,
311
+ "ai_generated": ai_generated,
312
+ "fallback_used": not ai_generated
313
  },
314
+ "message": f"Genererte {len(questions)} spørsmål om '{tema}'" +
315
+ (" med AI" if ai_generated else " med forbedret fallback")
316
  }
317
  except Exception as e:
318
  print(f"Error in generate_quiz_api: {str(e)}")
 
322
  "questions": []
323
  }
324
 
325
+ # Gradio interface
326
  def generate_quiz_gradio(tema, antall, api_key=None):
327
+ """Gradio wrapper"""
328
  if api_key and not validate_api_key(api_key):
329
  return "❌ **Ugyldig API-nøkkel**"
330
 
 
338
  return f"❌ **Feil:** {result['message']}"
339
 
340
  questions = result["questions"]
341
+ metadata = result["metadata"]
342
+
343
+ # Show different info based on whether AI was used
344
+ if metadata.get("ai_generated", False):
345
+ status_icon = "🤖"
346
+ status_text = "AI-generert"
347
+ else:
348
+ status_icon = "🔄"
349
+ status_text = "Forbedret fallback"
350
 
351
  output = f"✅ **Genererte {len(questions)} spørsmål om '{tema}'**\n\n"
352
+ output += f"{status_icon} **Type:** {status_text}\n"
353
+ output += f"⚙️ **Modell:** {metadata['model_used']}\n"
354
+ output += f"⏱️ **Tid:** {metadata['generation_time']}s\n\n"
355
 
356
  for i, q in enumerate(questions, 1):
357
  output += f"📝 **Spørsmål {i}:** {q['spørsmål']}\n"
 
365
  except Exception as e:
366
  return f"❌ **Feil:** {str(e)}"
367
 
368
+ # Health check
369
  def health_check():
370
+ return {
371
+ "status": "healthy",
372
+ "timestamp": time.time(),
373
+ "ai_available": bool(os.environ.get("HUGGINGFACE_API_KEY"))
374
+ }
375
 
376
+ # Gradio interface
377
+ with gr.Blocks(title="SoActi AI Quiz API - Forbedret") as demo:
378
+ gr.Markdown("# 🧠 SoActi AI Quiz API - Forbedret")
379
+ gr.Markdown("**🚀 Ekte AI-generering med forbedret fallback**")
380
 
381
  with gr.Row():
382
  with gr.Column():
383
  tema_input = gr.Textbox(
384
+ label="Tema",
385
+ value="verdens beste fotballspillere",
386
+ placeholder="Fotball, teknologi, historie, mat, filmer..."
387
  )
388
  antall_input = gr.Slider(
389
  minimum=1,
 
393
  value=3
394
  )
395
  api_key_input = gr.Textbox(
396
+ label="API-nøkkel",
397
  placeholder="Skriv inn API-nøkkel...",
398
  type="password"
399
  )
400
 
401
+ generate_btn = gr.Button("🚀 Generer Forbedret Quiz!", variant="primary")
402
 
403
  with gr.Column():
404
  output = gr.Textbox(
405
  label="Generert Quiz",
406
  lines=20,
407
+ placeholder="Skriv inn et tema og test den forbedrede AI-genereringen!"
408
  )
409
 
410
  generate_btn.click(
 
413
  outputs=output
414
  )
415
 
416
+ gr.Markdown("## 🔗 API Endepunkt")
417
  gr.Markdown("`POST https://Soacti-soacti-ai-quiz-api.hf.space/generate-quiz`")
 
418
 
419
+ # FastAPI setup
420
  from fastapi import FastAPI, HTTPException, Depends, Header
421
  from fastapi.middleware.cors import CORSMiddleware
422
  from pydantic import BaseModel
423
 
424
+ app = FastAPI(title="SoActi Quiz API - Forbedret")
425
 
426
  app.add_middleware(
427
  CORSMiddleware,
 
432
  )
433
 
434
  class QuizRequest(BaseModel):
435
+ tema: str
436
  språk: str = "no"
437
  antall_spørsmål: int = 3
438
  type: str = "sted"
 
450
 
451
  @app.post("/generate-quiz")
452
  async def api_generate_quiz(request: QuizRequest, api_key: str = Depends(get_api_key)):
 
453
  result = generate_quiz_api(
454
+ request.tema,
455
  request.språk,
456
  request.antall_spørsmål,
457
  request.type,