File size: 7,604 Bytes
c80f57a
2300b9a
 
 
c80f57a
 
 
 
3e1ff70
c80f57a
 
 
 
3e1ff70
c80f57a
 
 
3e1ff70
c80f57a
765f19b
 
 
 
 
 
 
2300b9a
765f19b
 
 
 
 
 
 
 
 
 
 
2300b9a
765f19b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2300b9a
c80f57a
 
 
 
 
 
 
 
3e1ff70
c80f57a
 
 
 
 
 
 
3e1ff70
c80f57a
3e1ff70
c80f57a
 
 
 
 
 
 
3e1ff70
c80f57a
 
 
 
 
 
2300b9a
c80f57a
765f19b
c80f57a
 
 
 
 
 
 
 
 
 
 
3e1ff70
c80f57a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765f19b
3e1ff70
c80f57a
 
 
 
3e1ff70
c80f57a
 
 
 
 
 
 
 
 
3e1ff70
c80f57a
765f19b
c80f57a
 
 
 
 
 
 
 
 
 
765f19b
c80f57a
 
 
 
 
 
 
 
765f19b
 
 
2300b9a
765f19b
2300b9a
 
 
 
c80f57a
765f19b
c80f57a
 
 
 
765f19b
 
 
c80f57a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765f19b
 
 
c80f57a
 
 
 
 
765f19b
 
c80f57a
 
765f19b
 
c80f57a
 
 
 
765f19b
c80f57a
3e1ff70
 
 
 
c80f57a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import os
import gradio as gr
import json
import time
from fastapi import FastAPI, HTTPException, Depends, Header
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel
from typing import Optional

# Hent API-nøkkel fra miljøvariabler
API_KEY = os.getenv("SOACTI_API_KEY")
if not API_KEY:
    raise ValueError("SOACTI_API_KEY miljøvariabel er ikke satt!")

# FastAPI app
app = FastAPI(title="SoActi AI Quiz API - Secure")
security = HTTPBearer()

# Hardkodede spørsmål (samme som før)
QUIZ_DATABASE = {
    "oslo": [
        {
            "spørsmål": "Hva heter Oslos hovedflyplass?",
            "alternativer": ["Fornebu", "Gardermoen", "Torp", "Rygge"],
            "korrekt_svar": 1,
            "forklaring": "Oslo lufthavn Gardermoen er Oslos hovedflyplass, åpnet i 1998."
        },
        {
            "spørsmål": "Hvilken fjord ligger Oslo ved?",
            "alternativer": ["Trondheimsfjorden", "Oslofjorden", "Hardangerfjorden", "Sognefjorden"],
            "korrekt_svar": 1,
            "forklaring": "Oslo ligger innerst i Oslofjorden."
        },
        {
            "spørsmål": "Hva heter Oslos berømte operahus?",
            "alternativer": ["Operaen", "Den Norske Opera", "Oslo Opera House", "Operahuset"],
            "korrekt_svar": 3,
            "forklaring": "Operahuset i Oslo åpnet i 2008."
        }
    ],
    "bergen": [
        {
            "spørsmål": "Hva kalles det fargerike kaiområdet i Bergen?",
            "alternativer": ["Bryggen", "Fisketorget", "Torgallmenningen", "Nordnes"],
            "korrekt_svar": 0,
            "forklaring": "Bryggen er UNESCOs verdensarvsted."
        },
        {
            "spørsmål": "Hvilket fjell kan man ta Fløibanen opp til?",
            "alternativer": ["Ulriken", "Fløyen", "Løvstakken", "Sandviksfjellet"],
            "korrekt_svar": 1,
            "forklaring": "Fløibanen går opp til Fløyen, 320 meter over havet."
        }
    ],
    "norsk historie": [
        {
            "spørsmål": "Hvilket år ble Norge selvstendig fra Danmark?",
            "alternativer": ["1814", "1905", "1821", "1830"],
            "korrekt_svar": 0,
            "forklaring": "Norge ble selvstendig fra Danmark i 1814."
        }
    ]
}

# API-nøkkel validering
async def verify_api_key(credentials: HTTPAuthorizationCredentials = Depends(security)):
    if credentials.credentials != API_KEY:
        raise HTTPException(
            status_code=401,
            detail="Ugyldig API-nøkkel"
        )
    return credentials.credentials

# Pydantic modeller
class QuizRequest(BaseModel):
    tema: str
    språk: str = "no"
    antall_spørsmål: int = 5
    type: str = "multiple_choice"
    vanskelighetsgrad: int = 3

# API endepunkter
@app.get("/health")
async def health_check():
    """Offentlig health check"""
    return {
        "status": "healthy", 
        "service": "SoActi AI Quiz API",
        "auth_required": True
    }

@app.post("/generate-quiz")
async def generate_quiz_secure(
    request: QuizRequest,
    api_key: str = Depends(verify_api_key)
):
    """Sikret quiz-generering - krever API-nøkkel"""
    try:
        tema_lower = request.tema.lower().strip()
        
        # Finn riktige spørsmål
        if tema_lower in QUIZ_DATABASE:
            questions = QUIZ_DATABASE[tema_lower]
        elif "oslo" in tema_lower:
            questions = QUIZ_DATABASE["oslo"]
        elif "bergen" in tema_lower:
            questions = QUIZ_DATABASE["bergen"]
        elif "historie" in tema_lower:
            questions = QUIZ_DATABASE["norsk historie"]
        else:
            questions = QUIZ_DATABASE["oslo"]
        
        # Begrens antall spørsmål
        selected_questions = questions[:request.antall_spørsmål]
        
        return {
            "success": True,
            "questions": selected_questions,
            "metadata": {
                "tema": request.tema,
                "språk": request.språk,
                "antall_generert": len(selected_questions),
                "model_used": "Fallback Database",
                "generation_time": 0.1,
                "auth_verified": True
            }
        }
        
    except Exception as e:
        raise HTTPException(
            status_code=500, 
            detail=f"Feil ved quiz-generering: {str(e)}"
        )

# Gradio interface (kun for testing)
def generate_quiz_ui(tema, antall, api_key_input):
    """Gradio wrapper med API-nøkkel input"""
    if not api_key_input:
        return "❌ API-nøkkel er påkrevd"
    
    if api_key_input != API_KEY:
        return "❌ Ugyldig API-nøkkel"
    
    try:
        tema_lower = tema.lower().strip()
        
        if tema_lower in QUIZ_DATABASE:
            questions = QUIZ_DATABASE[tema_lower]
        elif "oslo" in tema_lower:
            questions = QUIZ_DATABASE["oslo"]
        elif "bergen" in tema_lower:
            questions = QUIZ_DATABASE["bergen"]
        elif "historie" in tema_lower:
            questions = QUIZ_DATABASE["norsk historie"]
        else:
            questions = QUIZ_DATABASE["oslo"]
        
        selected_questions = questions[:antall]
        
        output = f"✅ **Genererte {len(selected_questions)} spørsmål om '{tema}'**\n\n"
        output += f"🔐 **Autentisert:** Ja\n"
        output += f"🤖 **Modell:** Fallback Database\n"
        output += f"⏱️ **Tid:** 0.1s\n\n"
        
        for i, q in enumerate(selected_questions, 1):
            output += f"📝 **Spørsmål {i}:** {q['spørsmål']}\n"
            for j, alt in enumerate(q['alternativer']):
                marker = "✅" if j == q['korrekt_svar'] else "❌"
                output += f"   {chr(65+j)}) {alt} {marker}\n"
            output += f"💡 **Forklaring:** {q['forklaring']}\n\n"
        
        return output
        
    except Exception as e:
        return f"❌ **Feil:** {str(e)}"

# Gradio interface
with gr.Blocks(title="SoActi AI Quiz API - Secure") as demo:
    gr.Markdown("# 🔐 SoActi AI Quiz API - Sikker Versjon")
    gr.Markdown("**API krever nå autentisering med Bearer token**")
    
    with gr.Row():
        with gr.Column():
            tema_input = gr.Textbox(
                label="Tema",
                value="Oslo",
                placeholder="Oslo, Bergen, Norsk historie"
            )
            antall_input = gr.Slider(
                minimum=1,
                maximum=5,
                step=1,
                label="Antall spørsmål",
                value=3
            )
            api_key_input = gr.Textbox(
                label="API-nøkkel (for testing)",
                type="password",
                placeholder="Skriv inn API-nøkkel..."
            )
            
            generate_btn = gr.Button("🚀 Generer Quiz", variant="primary")
        
        with gr.Column():
            output = gr.Textbox(
                label="Generert Quiz",
                lines=20,
                placeholder="Skriv inn API-nøkkel og klikk 'Generer Quiz'..."
            )
    
    generate_btn.click(
        fn=generate_quiz_ui,
        inputs=[tema_input, antall_input, api_key_input],
        outputs=output
    )
    
    gr.Markdown("## 🔗 API Endepunkt")
    gr.Markdown("`POST https://Soacti-soacti-ai-quiz-api.hf.space/generate-quiz`")
    gr.Markdown("**Header:** `Authorization: Bearer [din-api-nøkkel]`")

# Mount Gradio til FastAPI
app = gr.mount_gradio_app(app, demo, path="/")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=7860)