Entwickeln / Anleitungen

OpenAI-SDK

Wie Sie das OpenAI-SDK für Python und TypeScript auf das Gateway richten, Noirdoc-Header setzen und Fehler des Gateways von Fehlern des Anbieters unterscheiden.

Das Gateway nimmt Anfragen im Format der OpenAI-API an. Das OpenAI-SDK funktioniert deshalb unverändert, sobald base_url und api_key auf Noirdoc zeigen. Die Beispiele verwenden die Modell-ID qwen3.8-27b. Welche Modell-IDs Ihr Schlüssel aufrufen darf, liefert GET /v1/models (siehe Schnellstart).

SDK installieren

Installieren Sie das Paket openai für Python oder für Node.js.

Shell
pip install openai
Shell
npm install openai

Client einrichten

Setzen Sie base_url auf https://api.noirdoc.de/v1 und api_key auf Ihren px--Schlüssel. Das SDK sendet den Schlüssel im Header Authorization: Bearer.

Beide SDKs lesen die Werte auch aus den Umgebungsvariablen OPENAI_BASE_URL und OPENAI_API_KEY. So richten Sie bestehenden Code ein, ohne ihn zu ändern.

Der Client deckt alle OpenAI-Endpunkte des Gateways ab, zum Beispiel client.responses.create für POST /v1/responses und client.embeddings.create für POST /v1/embeddings.

Python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
)

response = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[{"role": "user", "content": "Hallo"}],
)
print(response.choices[0].message.content)
TypeScript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
});

const response = await client.chat.completions.create({
  model: "qwen3.8-27b",
  messages: [{ role: "user", content: "Hallo" }],
});
console.log(response.choices[0].message.content);

Maskierung einschalten

Der Header X-Noirdoc-Mask steuert die Maskierung je Anfrage. Mit default_headers sendet der Client ihn bei jeder Anfrage. Für eine einzelne Anfrage setzen Sie ihn in Python mit extra_headers, in TypeScript mit der Option headers.

Das Gateway wertet die Werte on und off aus und entfernt den Header, bevor es die Anfrage an den Anbieter weiterleitet. Ob der Header wirkt, hängt von der Maskierungsrichtlinie Ihrer Organisation ab (siehe Maskierung einschalten).

Embeddings, Audio und Bilder maskiert das Gateway nicht. Mit X-Noirdoc-Mask: on lehnt es Anfragen an diese Endpunkte mit masking_not_supported_for_endpoint (Statuscode 403) ab. Setzen Sie den Header dort nicht, auch nicht über default_headers. Nutzen Sie für diese Endpunkte einen eigenen Client ohne den Header.

Python
client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
    default_headers={"X-Noirdoc-Mask": "on"},
)

# Maskierung für diese Anfrage ausschalten
response = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[{"role": "user", "content": "Hallo"}],
    extra_headers={"X-Noirdoc-Mask": "off"},
)
TypeScript
const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
  defaultHeaders: { "X-Noirdoc-Mask": "on" },
});

// Maskierung für diese Anfrage ausschalten
const response = await client.chat.completions.create(
  {
    model: "qwen3.8-27b",
    messages: [{ role: "user", content: "Hallo" }],
  },
  { headers: { "X-Noirdoc-Mask": "off" } },
);

Anbieter aus der Antwort lesen

Der Antwort-Header X-Noirdoc-Provider nennt den Anbieter, der die Anfrage beantwortet hat. Das SDK gibt Header über die rohe Antwort heraus: in Python mit with_raw_response, in TypeScript mit .withResponse().

Python
raw = client.chat.completions.with_raw_response.create(
    model="qwen3.8-27b",
    messages=[{"role": "user", "content": "Hallo"}],
)
print(raw.headers.get("x-noirdoc-provider"))
response = raw.parse()
TypeScript
const { data, response } = await client.chat.completions
  .create({
    model: "qwen3.8-27b",
    messages: [{ role: "user", content: "Hallo" }],
  })
  .withResponse();
console.log(response.headers.get("x-noirdoc-provider"));

Fehler behandeln

Eine Fehlerantwort stammt entweder vom Gateway oder vom Anbieter.

  • Fehler des Gateways haben ein Fehlerobjekt mit "type": "proxy_error", einem code und einer message. Das SDK stellt type und code direkt am Fehler bereit. Prüfen Sie im Programm den code, nicht die message.
  • Fehler des Anbieters gibt das Gateway mit Statuscode und Body des Anbieters weiter. Der Header X-Noirdoc-Provider nennt auch hier den Anbieter. Fehlerantworten des Gateways tragen diesen Header nicht.
  • Ein fehlender oder ungültiger Schlüssel ergibt Statuscode 401 mit dem Body {"detail": "..."}. Das SDK meldet ihn als AuthenticationError; code und type sind dann leer.

Der Wert proxy_error ist ein fester Wert im Fehlerformat und bezeichnet Fehler des Gateways.

Python
import openai

try:
    response = client.chat.completions.create(
        model="qwen3.8-27b",
        messages=[{"role": "user", "content": "Hallo"}],
    )
except openai.APIStatusError as e:
    provider = e.response.headers.get("x-noirdoc-provider")
    if e.type == "proxy_error":
        print("Gateway:", e.status_code, e.code)
    elif provider:
        print("Anbieter:", provider, e.status_code)
    else:
        print("Gateway:", e.status_code, e.message)  # z. B. 401
TypeScript
try {
  const response = await client.chat.completions.create({
    model: "qwen3.8-27b",
    messages: [{ role: "user", content: "Hallo" }],
  });
} catch (err) {
  if (!(err instanceof OpenAI.APIError)) throw err;
  const provider = err.headers?.get("x-noirdoc-provider");
  if (err.type === "proxy_error") {
    console.log("Gateway:", err.status, err.code);
  } else if (provider) {
    console.log("Anbieter:", provider, err.status);
  } else {
    // z. B. 401
    console.log("Gateway:", err.status, err.message);
  }
}

Anfragen wiederholen

Das SDK wiederholt fehlgeschlagene Anfragen selbst, in der Standardeinstellung bis zu zweimal, unter anderem bei 429 und Statuscodes ab 500. Das Gateway versucht bei 429, 5xx und Netzwerkfehlern vorher schon den nächsten Anbieter für dasselbe Modell (Failover, siehe Anbieter & Routing).

Fehler wie insufficient_credit oder key_budget_exhausted (Statuscode 402) behebt eine Wiederholung nicht. Behandeln Sie sie im Programm.

Alle Codes und ihre Abhilfe stehen unter Fehlercodes.

StatusCodeBedeutung
400wrong_endpoint_for_modelDas Modell gehört zu einer anderen Endpunkt-Familie oder einem anderen API-Format als der aufgerufene Endpunkt.
402insufficient_creditDas Guthaben der Organisation ist aufgebraucht oder kleiner als die geschätzten Höchstkosten der Anfrage.
402key_budget_exhaustedDas Budget dieses Schlüssels ist für den laufenden Zeitraum aufgebraucht oder reicht für die geschätzten Kosten der Anfrage nicht aus.
403model_not_allowed_for_keyDas Modell gehört nicht zu den erlaubten Modellen dieses Schlüssels.
403masking_not_supported_for_endpointDer Endpunkt kann nicht maskieren, aber die Maskierungsrichtlinie ist enforced oder die Anfrage sendet X-Noirdoc-Mask: on.
404model_not_availableDie Modell-ID ist für die Organisation nicht verfügbar.
502provider_unreachableDas Gateway konnte keine Verbindung zum Anbieter herstellen, oder die Verbindung ist abgebrochen.
504provider_timeoutDer Anbieter hat nicht innerhalb der Wartezeit des Gateways geantwortet.