spicyapiDokumentation
SDKs
Hauptinhalt

Python-SDK

Das offizielle Python-SDK für SpicyAPI (spicyapi) – installieren, die erste Generierung schätzen und ausführen, eine lokale Datei hochladen, Webhooks prüfen und jeden Fehlercode nachschlagen.

spicyapi ist das offizielle Python-SDK für SpicyAPI. Es legt die Erzeugung von Bildern, Videos und Audio hinter ein einziges Client-Objekt: Es hängt Ihren API-Schlüssel an, macht aus dem Antwort-Envelope gewöhnliche Dictionaries, wartet mit vernünftigem Back-off auf das Ende eines Tasks, lädt lokale Dateien in einem Aufruf hoch und prüft Webhook-Signaturen in konstanter Zeit.

Es setzt Python 3.11 oder neuer voraus und hat keine Laufzeitabhängigkeiten. Das ist Absicht: Dieses Paket landet in einem Abhängigkeitsbaum, der Ihnen gehört, und jede Einschränkung, die es mitbringt, ist eine weitere Gelegenheit für einen Konflikt.

Ist das das richtige Werkzeug?

Sie möchten …Verwenden Sie
SpicyAPI aus Ihrem eigenen Python-Code aufrufenDieses SDK
Es aus Node.js oder TypeScript aufrufenDas TypeScript-SDK
Es aus Go, PHP oder Java aufrufenDas Go-, PHP- oder Java-SDK
Ohne Code aus einem Terminal heraus generierenDie CLI
Einen KI-Assistenten SpicyAPI für Sie aufrufen lassenDen MCP-Server und den Agent Skill
Ein Chat- oder Textmodell nutzenDie offizielle Bibliothek openai, anthropic oder google-genai, ausgerichtet auf SpicyAPI – siehe Text und Streaming

Installieren

pip install spicyapi

Legen Sie Ihren Schlüssel danach in die Umgebung, damit er weder in Ihrem Code noch in der History-Datei Ihrer Shell auftaucht:

export SPICY_API_KEY="sk-spicy-..."

Ihr erstes Ergebnis

Preis erfragen, entscheiden, Task anlegen, warten, Dateien lesen. Eine Kostenschätzung ist kostenlos und reserviert nichts.

import os, uuid
from spicyapi import SpicyClient, output_assets

client = SpicyClient()  # liest SPICY_API_KEY aus der Umgebung

model = client.get_model("MODEL_ID_FROM_CATALOG")
quote = client.quote_task(model=model["model"], input_data={"prompt": "a lantern in fog"})
print(quote["estimatedCost"], quote["maxCharge"])   # entscheiden, bevor Sie Geld ausgeben

task = client.create_task(
    model=model["model"],
    input_data={"prompt": "a lantern in fog"},
    idempotency_key=str(uuid.uuid4()),
    quote_id=quote["quoteId"],
    expected_cost=quote["estimatedCost"],
)
final = client.wait_for_terminal(task["taskId"])
for asset in output_assets(final):                  # Funktion des Moduls, keine Methode
    print(asset["url"])

MODEL_ID_FROM_CATALOG ist ein Platzhalter. Holen Sie sich eine echte ID aus dem authentifizierten Katalog – client.list_models(), also GET /api/v1/models – und nie aus dem Gedächtnis oder von einer alten Seite: Modelle kommen hinzu, werden pausiert und eingestellt. Bauen Sie input_data aus dem inputSchema genau dieses Modells, das list_models(include_schema=True) zurückgibt; jedes Modell nimmt andere Felder an.

Beträge kommen als Dezimalzeichenketten in US-Dollar zurück, nie als Floats, denn binäre Gleitkommazahlen können die meisten Dezimalbeträge nicht exakt speichern. Vergleichen und addieren Sie sie mit decimal.Decimal. Credits oder Punkte gibt es in dieser API nirgends.

wait_for_terminal kehrt bei jedem Endzustand zurück. Ein Endzustand ist kein erfolgreicher Zustand – prüfen Sie final["state"], bevor Sie die Ausgabe lesen.

Manche Endpunkte antworten mit Text statt mit Dateien. Lesen Sie zuerst output_text(final), wenn das Modell ein Transkript oder eine Beschreibung erzeugt; ein Client, der nur die Liste der Ergebnisdateien durchgeht, meldet bei einem vollkommen erfolgreichen Task, es sei nichts entstanden.

Mit einer lokalen Datei beginnen

Bild-zu-Video, Motivtausch und Bildbearbeitung brauchen Ihr Material zuerst auf unserer Seite. upload_file erledigt den dreistufigen Upload – Ticket, PUT in den Speicher, Commit – in einem Aufruf und gibt eine spicy://-URI zurück. Diese URI kommt in die Eingabe.

uploaded = client.upload_file("/path/to/reference.png")
task = client.create_task(
    model="MODEL_ID_FROM_CATALOG",
    input_data={"image": uploaded["uri"], "prompt": "slow dolly in"},
    idempotency_key=str(uuid.uuid4()),
)

Eine öffentlich erreichbare HTTPS-Adresse können Sie direkt in die Eingabe schreiben; dafür ist gar kein Upload nötig. Bilder werden bis 10 MiB angenommen, Audio und Video bis 90 MiB; alles Weitere steht unter Medien.

Webhooks

verify_webhook ist eine Funktion auf Modulebene, sodass ein Request-Handler sie nutzen kann, ohne einen Client zu bauen. Sie vergleicht in konstanter Zeit und prüft den Zeitstempel erst, wenn die Signatur gültig ist.

from spicyapi import verify_webhook

delivery = verify_webhook(
    raw_body=request.body,                      # exakt diese Bytes, vor jedem Parsen
    signature=request.headers["X-Webhook-Signature"],
    timestamp=request.headers["X-Webhook-Timestamp"],
    payload_version=request.headers["X-Webhook-Payload-Version"],
    secret=os.environ["SPICY_WEBHOOK_SECRET"],
)

Prüfen Sie die rohen Bytes. json.loads gefolgt von json.dumps verändert sie, und die Signatur passt danach nie wieder. Zustellungen werden wiederholt; entdoppeln Sie deshalb über die Zustellungs-ID. Das vollständige Zustellformat und den Wiederholungsplan finden Sie unter Webhooks.

Fehler

Jeder Fehlschlag löst SpicyApiError aus, mit status, code, request_id und retry_after_seconds. Verzweigen Sie über code, nie über den Text der Meldung – Meldungen werden übersetzt, Codes nicht.

HTTP 503 teilen sich drei verschiedene Business-Codes, der HTTP-Status allein genügt also nicht, um zu entscheiden, was zu tun ist:

CodeBedeutungWas zu tun ist
40003Hochgeladene Bytes passen nicht zum TicketMit einem frischen Ticket neu beginnen
40004Keine Bereitstellung bedient diese ParameterkombinationDen in der Meldung genannten Parameter ändern
40201Guthaben reicht nichtGuthaben aufladen
40901Der Preis hat sich vor dem Anlegen geändertNeu schätzen, denselben Idempotenzschlüssel behalten
503Eine Abhängigkeit ist kurz nicht erreichbarGemäß Retry-After warten
50301Das Modell hat gerade keine nutzbare Bereitstellung und keinen PreisKatalog neu laden, nicht dauerhaft nachfragen
50302Synchrone Generierung bei der Ausführung fehlgeschlagen, erstattetMit einem neuen Idempotenzschlüssel wiederholen

err.recovery liefert dieselbe Empfehlung zur Laufzeit. Nennen Sie request_id, wenn Sie den Support kontaktieren. Jeder Code steht unter Fehler.

Zwei Dinge, die Ihnen Geld sparen

Bleiben Sie pro Absendung bei einem Idempotenzschlüssel. Verwenden Sie ihn für jedes erneute Senden derselben Absendung wieder, auch nach einem Timeout oder einem Verbindungsabbruch. Eine verlorene Antwort ist kein Beweis dafür, dass der Task nicht angelegt wurde – ein frischer Schlüssel macht aus einem unbekannten Ausgang einen zweiten kostenpflichtigen Task. Siehe Idempotenz.

Ein erfolgreicher Task wird berechnet, auch wenn das Ergebnis enttäuscht. Holen Sie zuerst eine Kostenschätzung ein, wenn es auf den Preis ankommt; quote_task reserviert nichts und legt nichts an.

Was dieses Paket nicht tut

  • Textmodelle. Sie sprechen die Formate von OpenAI, Anthropic und Gemini, deshalb funktionieren die offiziellen Bibliotheken openai, anthropic und google-genai bereits – richten Sie sie mit demselben Schlüssel auf https://api.spicyapi.ai/v1 aus. Siehe Text und Streaming.
  • Browser-, Mobil- und Desktop-Apps. Liefern Sie diesen Schlüssel niemals in einer Anwendung aus: Ein in einen Client einkompilierter Schlüssel ist ein öffentlicher Schlüssel. Rufen Sie von Ihrem Server aus auf.
  • Ein Modell auswählen oder seine Felder ausfüllen. Es reicht Ihnen den Katalog und das Schema jedes Modells; was Sie senden, entscheiden Sie.
  • Einen Task abbrechen. Ist ein Task erst angenommen, läuft er bis zum Ende. Ihr Programm zu beenden, stoppt nur Ihr Warten.

Quellcode

Das Paket steht unter MIT-Lizenz und wird offen unter github.com/spicyapi-ai/spicy-python entwickelt. Sein README ist die kürzeste vollständige Führung durch den Client; diese Seite ergänzt die Konzepte drumherum.

Nächste Schritte

Auf dieser Seite