Files
breakpilot-lehrer/backend-lehrer/klausur_service_proxy.py
Benjamin Boenisch 5a31f52310 Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:26 +01:00

136 lines
4.7 KiB
Python

"""
Klausur-Service API Proxy
Routes API requests from /api/klausur/* to the klausur-service microservice
"""
import os
import jwt
import datetime
import httpx
from fastapi import APIRouter, Request, HTTPException, Response
# Klausur Service URL
KLAUSUR_SERVICE_URL = os.getenv("KLAUSUR_SERVICE_URL", "http://klausur-service:8086")
JWT_SECRET = os.getenv("JWT_SECRET", "your-super-secret-jwt-key-change-in-production")
ENVIRONMENT = os.getenv("ENVIRONMENT", "development")
# Demo teacher UUID for development mode
DEMO_TEACHER_ID = "e9484ad9-32ee-4f2b-a4e1-d182e02ccf20"
router = APIRouter(prefix="/klausur", tags=["klausur"])
def get_demo_token() -> str:
"""Generate a demo JWT token for development mode"""
payload = {
"user_id": DEMO_TEACHER_ID,
"email": "demo@breakpilot.app",
"role": "admin",
"exp": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=24),
"iat": datetime.datetime.now(datetime.timezone.utc)
}
return jwt.encode(payload, JWT_SECRET, algorithm="HS256")
async def proxy_request(request: Request, path: str) -> Response:
"""Forward a request to the klausur service"""
url = f"{KLAUSUR_SERVICE_URL}/api/v1{path}"
# Forward headers, especially Authorization
headers = {}
if "authorization" in request.headers:
headers["Authorization"] = request.headers["authorization"]
elif ENVIRONMENT == "development":
# In development mode, use demo token if no auth provided
demo_token = get_demo_token()
headers["Authorization"] = f"Bearer {demo_token}"
if "content-type" in request.headers:
headers["Content-Type"] = request.headers["content-type"]
# Get request body for POST/PUT/PATCH/DELETE
body = None
if request.method in ("POST", "PUT", "PATCH", "DELETE"):
body = await request.body()
async with httpx.AsyncClient(timeout=60.0) as client:
try:
response = await client.request(
method=request.method,
url=url,
headers=headers,
content=body,
params=request.query_params
)
return Response(
content=response.content,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.headers.get("content-type", "application/json")
)
except httpx.ConnectError:
raise HTTPException(
status_code=503,
detail="Klausur service unavailable"
)
except httpx.TimeoutException:
raise HTTPException(
status_code=504,
detail="Klausur service timeout"
)
# Health check
@router.get("/health")
async def health():
"""Health check for klausur service connection"""
async with httpx.AsyncClient(timeout=5.0) as client:
try:
response = await client.get(f"{KLAUSUR_SERVICE_URL}/health")
return {"klausur_service": "healthy", "connected": response.status_code == 200}
except Exception:
return {"klausur_service": "unhealthy", "connected": False}
# Klausuren
@router.api_route("/klausuren", methods=["GET", "POST"])
async def klausuren(request: Request):
return await proxy_request(request, "/klausuren")
@router.api_route("/klausuren/{klausur_id}", methods=["GET", "PUT", "DELETE"])
async def klausur_by_id(klausur_id: str, request: Request):
return await proxy_request(request, f"/klausuren/{klausur_id}")
# Students
@router.api_route("/klausuren/{klausur_id}/students", methods=["GET", "POST"])
async def klausur_students(klausur_id: str, request: Request):
return await proxy_request(request, f"/klausuren/{klausur_id}/students")
@router.api_route("/students/{student_id}", methods=["GET", "DELETE"])
async def student_by_id(student_id: str, request: Request):
return await proxy_request(request, f"/students/{student_id}")
# Grading
@router.api_route("/students/{student_id}/criteria", methods=["PUT"])
async def update_criteria(student_id: str, request: Request):
return await proxy_request(request, f"/students/{student_id}/criteria")
@router.api_route("/students/{student_id}/gutachten", methods=["PUT"])
async def update_gutachten(student_id: str, request: Request):
return await proxy_request(request, f"/students/{student_id}/gutachten")
@router.api_route("/students/{student_id}/finalize", methods=["POST"])
async def finalize_student(student_id: str, request: Request):
return await proxy_request(request, f"/students/{student_id}/finalize")
# Grade info
@router.get("/grade-info")
async def grade_info(request: Request):
return await proxy_request(request, "/grade-info")