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.
pip install openainpm install openaiClient 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.
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)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.
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"},
)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().
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()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", einemcodeund einermessage. Das SDK stellttypeundcodedirekt am Fehler bereit. Prüfen Sie im Programm dencode, nicht diemessage. - Fehler des Anbieters gibt das Gateway mit Statuscode und Body des Anbieters weiter. Der Header
X-Noirdoc-Providernennt 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 alsAuthenticationError;codeundtypesind dann leer.
Der Wert proxy_error ist ein fester Wert im Fehlerformat und bezeichnet Fehler des Gateways.
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. 401try {
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.
| Status | Code | Bedeutung |
|---|---|---|
| 400 | wrong_endpoint_for_model | Das Modell gehört zu einer anderen Endpunkt-Familie oder einem anderen API-Format als der aufgerufene Endpunkt. |
| 402 | insufficient_credit | Das Guthaben der Organisation ist aufgebraucht oder kleiner als die geschätzten Höchstkosten der Anfrage. |
| 402 | key_budget_exhausted | Das Budget dieses Schlüssels ist für den laufenden Zeitraum aufgebraucht oder reicht für die geschätzten Kosten der Anfrage nicht aus. |
| 403 | model_not_allowed_for_key | Das Modell gehört nicht zu den erlaubten Modellen dieses Schlüssels. |
| 403 | masking_not_supported_for_endpoint | Der Endpunkt kann nicht maskieren, aber die Maskierungsrichtlinie ist enforced oder die Anfrage sendet X-Noirdoc-Mask: on. |
| 404 | model_not_available | Die Modell-ID ist für die Organisation nicht verfügbar. |
| 502 | provider_unreachable | Das Gateway konnte keine Verbindung zum Anbieter herstellen, oder die Verbindung ist abgebrochen. |
| 504 | provider_timeout | Der Anbieter hat nicht innerhalb der Wartezeit des Gateways geantwortet. |