API Dokumentation

Vollständige Dokumentation für die CharGraph REST API zur STL-Generierung und Pattern-Verwaltung.

API Dokumentation

CharGraph API für Zeit-zu-Wörter Konvertierung, Pattern-Validierung und STL-Generierung.


Übersicht

Die CharGraph API bietet Endpoints für:

  • Zeit-zu-Wörter Konvertierung (neue V0.4 Funktion)
  • Pattern-Validierung (neue V0.4 Funktion)
  • STL-Datei-Generierung aus Pattern-Strings
  • 3D-Modell-Rendering mit OpenSCAD

Base URL: https://www.chargraph.de/api

🔗 Interaktive API-Dokumentation (Swagger/OpenAPI)

Alle Endpoints sind interaktiv dokumentiert und können direkt im Browser getestet werden:

Swagger UI: https://www.chargraph.de/api/docs

Dort können Sie:

  • ✅ Alle Endpoints sehen
  • ✅ Request/Response Schemas ansehen
  • ✅ API direkt aus dem Browser testen (Try it out)
  • ✅ Automatisch generierte Dokumentation für alle Parameter

Alternative (OpenAPI JSON):


Endpoints

POST /api/time-words (NEW - V0.4)

Konvertiert eine Uhrzeit zu deutschen Wörtern basierend auf Pattern-Vorlage.

Request:

POST /api/time-words HTTP/1.1
Content-Type: application/json

{
  "pattern": "ES_IST_BALD...",
  "hour": 14,
  "minute": 28
}

Request Body:

ParameterTypErforderlichBeschreibung
patternstringJaGrid-Pattern (110 Zeichen)
hournumberJaStunde (0-23)
minutenumberJaMinute (0-59)

Response (Success):

{
  "words": ["ES", "IST", "KURZ", "VOR", "HALB", "DREI"],
  "led_count": 2,
  "led_direction": "right",
  "text": "ES IST KURZ VOR HALB DREI"
}

Response Fields (Success):

FeldTypBeschreibung
wordsarray[string]Array deutscher Wörter in zeitlicher Reihenfolge
led_countnumberAnzahl der Minuten-LEDs (0-4)
led_directionstringLED-Richtung: "left" (NACH, addiv) oder "right" (VOR, subtrakt)
textstringKompletter Zeittext als String (Wörter mit Leerzeichen)

Response (Error):

{
  "error": "Invalid pattern length",
  "details": "Pattern must be exactly 110 characters"
}

Status Codes:

  • 200 OK - Erfolgreich konvertiert
  • 400 Bad Request - Ungültige Eingabe (Pattern falsch formatiert)
  • 422 Unprocessable Entity - Pattern enthält blockierte Wörter
  • 500 Internal Server Error - Server-Fehler

POST /api/validate (NEW - V0.4)

Validiert ein 110-Zeichen Pattern auf Korrektheit.

Request:

POST /api/validate HTTP/1.1
Content-Type: application/json

{
  "pattern": "ES_IST_BALD..."
}

Request Body:

ParameterTypErforderlichBeschreibung
patternstringJaGrid-Pattern (110 Zeichen)

Response (Valid):

{
  "valid": true,
  "errors": [],
  "warnings": []
}

Response (Invalid):

{
  "valid": false,
  "errors": [
    "FÜNF missing",
    "ZEHN missing"
  ],
  "warnings": [
    "INFO: No gap between IST and NACHT"
  ]
}

Response Fields:

FeldTypBeschreibung
validbooleanTrue wenn Pattern gültig, False wenn Fehler vorhanden
errorsarray[string]Liste kritischer Fehler (leeres Array wenn gültig)
warningsarray[string]Liste von Warnungen/Hinweisen (leeres Array wenn keine)

Status Codes:

  • 200 OK - Validierung abgeschlossen (gültig oder ungültig)
  • 400 Bad Request - Ungültige Eingabe (z.B. falsche Länge oder ungültige Zeichen)
  • 500 Internal Server Error - Server-Fehler

POST /api/render (Existing)

Generiert eine STL-Datei aus einem Pattern-String mittels OpenSCAD.

Request:

POST /api/render HTTP/1.1
Content-Type: application/json

{
  "pattern": "wordclock-example",
  "patterntext": "ES_IST_BALD...",
  "thickness": 0.8,
  "height": 11
}

Request Body:

ParameterTypErforderlichBeschreibung
patternstringJaDateiname des STL (ohne .stl)
patterntextstringJaGrid-Pattern (110 Zeichen)
thicknessfloatNeinExtrusion-Dicke in mm (default: 0.8)
heightfloatNeinRahmenhöhe in mm (default: 11)

Response (Success):

{
  "ok": true,
  "file": "wordclock-example.stl"
}

Response Fields (Success):

FeldTypBeschreibung
okbooleanTrue wenn erfolgreich generiert
filestringDateiname des generierten STL (ohne Pfad)

Response (Error):

{
  "detail": "Inhalt blockiert. Verbotene Wörter gefunden: NAZI, HATE"
}

Response Fields (Error):

FeldTypBeschreibung
detailstringFehlermeldung mit Details zum Problem

Status Codes:

  • 200 OK - Erfolgreich generiert
  • 400 Bad Request - Ungültige Eingabe (Pattern-Format, Dateiname ungültig)
  • 422 Unprocessable Entity - Blacklist-Wörter gefunden (Sicherheit)
  • 500 Internal Server Error - Server-Fehler
  • 504 Gateway Timeout - Rendering-Timeout (>120s OpenSCAD)

GET /api/models/:filename

Lädt eine generierte STL-Datei herunter.

Request:

GET /api/models/wordclock-example.stl HTTP/1.1

Response:

Content-Type: model/stl
Content-Disposition: attachment; filename="wordclock-example.stl"

[STL Binary Data]

Response (Success):

HeaderWertBeschreibung
Content-Typemodel/stlMIME-Type für STL-Dateien
Content-Dispositionattachment; filename="..."Browser-Anweisung zum Download mit Dateiname

Die Response-Body enthält die rohen Binary-Daten der STL-Datei (ca. 500 KB - 2 MB).

Status Codes:

  • 200 OK - Datei gefunden und heruntergeladen
  • 404 Not Found - Datei existiert nicht oder wurde gelöscht
  • 500 Internal Server Error - Server-Fehler

Verwendung

Workflow (Empfohlener Prozess)

Für eine typische Anwendung empfehlen wir diesen Workflow:

  1. Pattern validieren (POST /api/validate)

    • Überprüfe ob das Pattern gültig ist
    • Lese Fehler und Warnungen
  2. Zeit zu Wörtern konvertieren (POST /api/time-words)

    • Nutze die validierte Pattern
    • Erhalte Words, LED-Position, Text
    • Zeige Ergebnis in UI an
  3. STL-Datei generieren (POST /api/render) - optional

    • Nur wenn Benutzer Export wünscht
    • Nutze das validierte Pattern
    • Speichere Dateiname
  4. STL-Datei herunterladen (GET /api/models/:filename) - optional

    • Lade die generierte Datei herunter
    • Browser startet automatischen Download

Mit JavaScript (Fetch API)

1. Zeit zu Wörtern konvertieren (V0.4)

async function getWordsForTime(pattern, hour, minute) {
    const response = await fetch('https://www.chargraph.de/api/time-words', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ pattern, hour, minute })
    });

    if (!response.ok) {
        console.error('API Fehler:', response.status);
        return null;
    }

    const data = await response.json();
    console.log('Wörter:', data.words.join(' '));
    console.log('LED-Position:', data.led_count, data.led_direction);
    return data;
}

// Verwendung
const pattern = "ES_IST_BALDFÜNFZEHN..."; // 110 Zeichen
getWordsForTime(pattern, 14, 28); // 14:28 Uhr

2. Pattern validieren (V0.4)

async function validatePattern(pattern) {
    const response = await fetch('https://www.chargraph.de/api/validate', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ pattern })
    });

    const data = await response.json();

    if (data.valid) {
        console.log('✓ Pattern ist gültig!');
    } else {
        console.error('✗ Fehler:', data.errors);
        if (data.warnings.length > 0) {
            console.warn('⚠️ Warnungen:', data.warnings);
        }
    }
    return data;
}

// Verwendung
validatePattern(pattern);

3. STL generieren

async function generateSTL(pattern, filename, thickness = 0.8, height = 11) {
    const response = await fetch('https://www.chargraph.de/api/render', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            pattern: filename,
            patterntext: pattern,
            thickness,
            height
        })
    });

    if (!response.ok) {
        const error = await response.json();
        console.error('Fehler:', error.detail);
        return null;
    }

    const data = await response.json();
    console.log('✓ STL generiert:', data.file);

    // Download-Link
    const downloadUrl = `https://www.chargraph.de/api/models/${data.file}`;
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = data.file;
    link.click();

    return data;
}

// Verwendung
const pattern = "ES_IST_BALDFÜNFZEHN...";
generateSTL(pattern, "meine-uhr", 0.8, 11);

Mit Python

import requests

def get_words_for_time(pattern, hour, minute):
    """Zeit zu Wörtern konvertieren"""
    url = 'https://www.chargraph.de/api/time-words'
    payload = {
        'pattern': pattern,
        'hour': hour,
        'minute': minute
    }

    response = requests.post(url, json=payload)
    data = response.json()

    print(f"Wörter: {' '.join(data['words'])}")
    print(f"LEDs: {data['led_count']} ({data['led_direction']})")
    return data

def validate_pattern(pattern):
    """Pattern validieren"""
    url = 'https://www.chargraph.de/api/validate'
    response = requests.post(url, json={'pattern': pattern})
    data = response.json()

    if data['valid']:
        print("✓ Pattern ist gültig!")
    else:
        print(f"✗ Fehler: {', '.join(data['errors'])}")
        if data['warnings']:
            print(f"⚠️ Warnungen: {', '.join(data['warnings'])}")

    return data

def generate_stl(pattern, filename, thickness=0.8, height=11):
    """STL generieren"""
    url = 'https://www.chargraph.de/api/render'
    payload = {
        'pattern': filename,
        'patterntext': pattern,
        'thickness': thickness,
        'height': height
    }

    response = requests.post(url, json=payload)

    if response.status_code == 200:
        data = response.json()
        stl_file = data['file']

        # STL herunterladen
        download_url = f"https://www.chargraph.de/api/models/{stl_file}"
        stl_response = requests.get(download_url)

        with open(stl_file, 'wb') as f:
            f.write(stl_response.content)

        print(f"✓ STL gespeichert: {stl_file}")
    else:
        error = response.json()
        print(f"✗ Fehler: {error.get('detail', 'Unbekannter Fehler')}")

# Verwendung
pattern = "ES_IST_BALDFÜNFZEHN..."
get_words_for_time(pattern, 14, 28)
validate_pattern(pattern)
generate_stl(pattern, "meine-uhr")

Mit cURL

# Zeit zu Wörtern konvertieren
curl -X POST https://www.chargraph.de/api/time-words \
  -H "Content-Type: application/json" \
  -d '{"pattern":"ES_IST_BALD...","hour":14,"minute":28}' \
  | jq .

# Pattern validieren
curl -X POST https://www.chargraph.de/api/validate \
  -H "Content-Type: application/json" \
  -d '{"pattern":"ES_IST_BALD..."}' \
  | jq .

# STL generieren
curl -X POST https://www.chargraph.de/api/render \
  -H "Content-Type: application/json" \
  -d '{"pattern":"test","patterntext":"ES_IST_BALD...","thickness":0.8,"height":11}' \
  | jq .

# STL herunterladen
curl -O https://www.chargraph.de/api/models/test.stl

Rate Limits

  • 10 Requests pro Minute pro IP
  • 100 Requests pro Tag pro IP

Bei Überschreitung:

{
  "status": "error",
  "message": "Rate limit exceeded",
  "retry_after": 60
}

Pattern-Format

Anforderungen

  • Länge: Exakt 110 Zeichen
  • Zeichen: A-Z, Umlaute (Ä, Ö, Ü), Unterstrich (_)
  • Format: 10 Zeilen × 11 Spalten

Beispiel

ES_IST_BALD
FÜNFZEHNVOR
NACHHALB___
ZWEI_EINS__
DREIVIERELF
FÜNFSECHS__
SIEBENZWÖLF
ZEHNNEUN___
ACHT_______
UHR________

Als String:

ES_IST_BALDFÜNFZEHNVORNACHHALB___ZWEI_EINS__DREIVIEREFFFÜNFSECHS__SIEBENZWÖLFZEHNNEUN___ACHT_______UHR________

Fehler-Codes

CodeBeschreibung
INVALID_PATTERNPattern-String ungültig
INVALID_LENGTHPattern nicht 110 Zeichen
INVALID_CHARSUngültige Zeichen im Pattern
INVALID_FILENAMEDateiname ungültig
TIMEOUTRendering-Timeout (>120s)
OPENSCAD_ERROROpenSCAD Fehler
RATE_LIMITRate Limit überschritten

Best Practices

1. Validierung vor API-Call

function validatePattern(pattern) {
    if (pattern.length !== 110) {
        return { valid: false, error: 'Länge muss 110 sein' };
    }

    if (!/^[A-ZÄÖÜ_]+$/.test(pattern)) {
        return { valid: false, error: 'Ungültige Zeichen' };
    }

    return { valid: true };
}

2. Timeout handling

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30s

try {
    const response = await fetch(url, {
        signal: controller.signal,
        ...options
    });
} catch (error) {
    if (error.name === 'AbortError') {
        console.error('Request timeout');
    }
} finally {
    clearTimeout(timeoutId);
}

3. Retry-Logik

async function generateWithRetry(pattern, filename, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await generateSTL(pattern, filename);
        } catch (error) {
            if (i === maxRetries - 1) throw error;
            await new Promise(r => setTimeout(r, 1000 * (i + 1)));
        }
    }
}

Technische Details

OpenSCAD Rendering

Die API verwendet OpenSCAD für 3D-Rendering:

  • Timeout: 120 Sekunden
  • Font: WordclockFont2.ttf
  • Ausgabe: Binary STL
  • Größe: ~500 KB - 2 MB

Datei-Speicherung

  • Speicherdauer: 24 Stunden
  • Speicherort: /var/lib/models/
  • Automatische Löschung: Nach 24h

Support

Bei API-Problemen:

  • Prüfe Browser-Console für detaillierte Fehler
  • Teste mit cURL für Netzwerk-Probleme
  • Öffne ein GitHub Issue mit Request/Response

API Version: 2.0 (mit V0.4 time-words und validate Endpoints) Editor Version: V0.4 (API-basiert) Letzte Aktualisierung: Januar 2026