Files
boc/academy-gemini-direct.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

206 lines
7.5 KiB
Python

#!/usr/bin/env python3
"""
quiXzoom Academy — Direkt Gemini Integration
Använder Gemini API direkt (via AAMOS nyckel) för att generera bildbeskrivningar
"""
import requests
import json
import os
from datetime import datetime
from pathlib import Path
# Gemini API-konfiguration (från AAMOS)
GEMINI_API_KEY = "AIzaSyANo7g3-EZTuH_VAw1ZRzW7n-A39ewIhqo"
GEMINI_ENDPOINT = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent"
# Lektionsbilder som ska genereras
LESSON_IMAGES = {
"m1l1": {
"title": "Välkommen till quiXzoom",
"prompt": "Beskriv en pedagogisk illustration: En glad person med smartphone fotograferar en bro i solnedgång. Modern, ren illustration med blå och gröna färger. 16:9 format."
},
"m2l1": {
"title": "AI-granskning av bilder",
"prompt": "Beskriv en teknisk illustration: En bild delad i två delar. Vänster: Originalbild på en bro. Höger: Samma bild med AI-analys-overlay som markerar skärpa, ljus, komposition med färgkodade indikatorer. Futuristisk men pedagogisk stil."
},
"m2l2": {
"title": "Ljus och exponering",
"prompt": "Beskriv en pedagogisk jämförelse: Tre bilder i rad som visar samma bro. 1. Underexponerad (för mörk), 2. Perfekt exponerad (gyllene timmen), 3. Överexponerad (för ljus). Fotorealistisk stil."
},
"m2l3": {
"title": "Fokus och skärpa",
"prompt": "Beskriv en pedagogisk bild: Två bilder som visar en vägskylt. Vänster: Suddig, oskarp. Höger: Knivskarp med förstoringsglas-effekt som visar detaljer. Fotorealistisk med grafiska element."
},
"m2l4": {
"title": "Framing och komposition",
"prompt": "Beskriv en pedagogisk diagram-bild: En bro fotograferad med korrekt komposition. Overlay med rule of thirds grid, pil som pekar på huvudobjektet, grön markering för bra komposition."
},
"m3l1": {
"title": "GPS-accuracy",
"prompt": "Beskriv en teknisk illustration: En karta över en stad med en smartphone i mitten. 4 GPS-satelliter ovanför skickar signaler till telefonen. Färgkodade accuracy-cirklar: grön (noggrann), gul (medel), röd (låg)."
},
"m4l1": {
"title": "Personlig säkerhet",
"prompt": "Beskriv en illustration: En person med reflexväst och smartphone fotograferar en bro från säkert avstånd. Trafikkegel, varselväst, säkerhetsavstånd markerat. Modern, vänlig stil."
},
"m5l1": {
"title": "Batch-fotografering",
"prompt": "Beskriv en karta-baserad illustration: En stiliserad karta med fotopunkter (A, B, C, D, E) kopplade med en optimerad grön rutt. En person med smartphone följer rutten effektivt."
},
"m6l1": {
"title": "Utbetalningsflöde",
"prompt": "Beskriv ett flödesdiagram: Horisontellt flöde som visar 1. Godkänd fotografi → 2. AI-granskning → 3. Godkännande → 4. Utbetalning → 5. Pengar på kontot. Modern, ren illustration med ikoner."
}
}
def generate_with_gemini(prompt: str) -> str:
"""Generera text med Gemini API"""
url = f"{GEMINI_ENDPOINT}?key={GEMINI_API_KEY}"
payload = {
"contents": [{
"parts": [{
"text": prompt
}]
}],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 1000
}
}
try:
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 200:
data = response.json()
# Extrahera text från response
if 'candidates' in data and len(data['candidates']) > 0:
candidate = data['candidates'][0]
if 'content' in candidate and 'parts' in candidate['content']:
parts = candidate['content']['parts']
if len(parts) > 0 and 'text' in parts[0]:
return parts[0]['text']
return None
else:
print(f" ⚠️ Gemini API fel: {response.status_code}")
print(f" {response.text[:200]}")
return None
except Exception as e:
print(f" ⚠️ Fel: {e}")
return None
def generate_image_description(lesson_id: str) -> dict:
"""Generera bildbeskrivning för en lektion"""
lesson = LESSON_IMAGES.get(lesson_id)
if not lesson:
return None
print(f"🎨 {lesson['title']}")
# Generera detaljerad bildbeskrivning
prompt = f"""Du är en expert på pedagogiska illustrationer för online-utbildningar.
Beskriv i detalj en illustration för följande lektion:
Titel: {lesson['title']}
Beskrivning: {lesson['prompt']}
Ge en detaljerad beskrivning som kan användas för att:
1. Generera en bild med AI
2. Förstå vad som ska visas i lektionen
Beskrivningen ska vara på svenska och inkludera:
- Huvudobjekt och deras placering
- Färger och stil
- Viktiga detaljer som måste synas
- Pedagogiska element"""
description = generate_with_gemini(prompt)
if description:
return {
"lesson_id": lesson_id,
"title": lesson['title'],
"description": description,
"generated_at": datetime.utcnow().isoformat(),
"status": "ready"
}
else:
return None
def generate_all_images():
"""Generera alla bildbeskrivningar"""
print("🚀 quiXzoom Academy — Gemini Bildgenerering")
print("=" * 60)
print(f"Använder Gemini API med nyckel: {GEMINI_API_KEY[:15]}...")
print("")
results = []
output_dir = Path("academy-generated")
output_dir.mkdir(exist_ok=True)
for lesson_id, lesson in LESSON_IMAGES.items():
result = generate_image_description(lesson_id)
if result:
results.append(result)
# Spara till fil
with open(output_dir / f"{lesson_id}.json", "w", encoding="utf-8") as f:
json.dump(result, f, indent=2, ensure_ascii=False)
print(f" ✅ Sparad till academy-generated/{lesson_id}.json")
else:
print(f" ❌ Kunde inte generera")
print("")
# Spara sammanfattning
summary = {
"generated_at": datetime.utcnow().isoformat(),
"total_images": len(LESSON_IMAGES),
"successful": len(results),
"failed": len(LESSON_IMAGES) - len(results),
"images": results
}
with open(output_dir / "summary.json", "w", encoding="utf-8") as f:
json.dump(summary, f, indent=2, ensure_ascii=False)
print("=" * 60)
print(f"{len(results)}/{len(LESSON_IMAGES)} bildbeskrivningar genererade")
print(f"📄 Sparade i academy-generated/")
return summary
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "--generate":
generate_all_images()
else:
print("Användning:")
print(" python academy-gemini-direct.py --generate")
print("")
print("Detta kommer att:")
print(" 1. Ansluta till Gemini API")
print(" 2. Generera bildbeskrivningar för alla lektioner")
print(" 3. Spara resultat i academy-generated/")
print("")
print("Testar anslutning...")
# Testa anslutning
test = generate_with_gemini("Svara bara: Gemini fungerar!")
if test:
print(f"✅ Gemini är tillgänglig!")
print(f" Svar: {test[:100]}")
else:
print("❌ Kunde inte ansluta till Gemini")