Guides SDK
Python
Utilisez le paquet Python officiel openai avec api14 : client synchrone et asynchrone, chat, streaming, outils, sorties Pydantic et erreurs.
Utilisez le paquet Python officiel openai avec api14. Définissez base_url et api_key ; utilisez n'importe quel identifiant de modèle (par exemple openai/gpt-5-mini) comme model.
Installation
pip install openai
export API14_API_KEY="sk-api14-..."
Configuration
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api14.com/api/v1",
api_key=os.environ["API14_API_KEY"],
)
Un client asynchrone existe aussi : from openai import AsyncOpenAI prend les mêmes arguments. Utilisez-le quand vous lancez beaucoup de requêtes à la fois, par exemple dans un serveur web ou un traitement par lots :
import asyncio
from openai import AsyncOpenAI
aclient = AsyncOpenAI(base_url="https://api14.com/api/v1", api_key=os.environ["API14_API_KEY"])
async def ask(q):
r = await aclient.chat.completions.create(model="openai/gpt-5-mini", messages=[{"role": "user", "content": q}])
return r.choices[0].message.content
async def main():
return await asyncio.gather(*(ask(q) for q in ["What is RAG?", "What is a token?"]))
answers = asyncio.run(main())
Gardez la concurrence sous la limite de requêtes par minute de votre forfait. Voir Guide : traitement par lots.
Sans argument, OpenAI() lit OPENAI_BASE_URL et OPENAI_API_KEY, vous pouvez donc faire pointer une application existante vers api14 uniquement via l'environnement :
export OPENAI_BASE_URL="https://api14.com/api/v1"
export OPENAI_API_KEY="sk-api14-..."
Chat
result = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[{"role": "user", "content": "Explain vector databases in two sentences."}],
)
print(result.choices[0].message.content)
Streaming
stream = client.chat.completions.create(
model="anthropic/claude-sonnet-4.5",
messages=[{"role": "user", "content": "Write a haiku about APIs."}],
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="")
Voir Streaming.
Appel d'outils
import json
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "What's the weather in Istanbul?"}]
while True:
res = client.chat.completions.create(model="openai/gpt-5-mini", messages=messages, tools=tools)
msg = res.choices[0].message
if not msg.tool_calls:
break
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(**args) # votre fonction
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
print(msg.content)
Voir Appel d'outils.
Sortie structurée
client.chat.completions.parse convertit un modèle Pydantic en JSON Schema strict et renvoie l'objet analysé. Il nécessite une version récente de openai ; les anciennes versions 1.x l'exposent sous client.beta.chat.completions.parse. Utilisez un modèle dont les supported_parameters incluent structured_outputs ou response_format :
from pydantic import BaseModel
class Person(BaseModel):
name: str
born: int
city: str
res = client.chat.completions.parse(
model="openai/gpt-5-mini",
messages=[{"role": "user", "content": "Extract: Ada Lovelace, born 1815 in London."}],
response_format=Person,
)
person = res.choices[0].message.parsed # Person(name='Ada Lovelace', born=1815, city='London')
Voir Sorties structurées.
Image en entrée
import base64
image = base64.b64encode(open("photo.png", "rb").read()).decode()
res = client.chat.completions.create(
model="google/gemini-2.5-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What is in this picture?"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image}"}},
],
}],
)
Une URL publique https:// fonctionne aussi. Voir Vision et fichiers.
Images
result = client.images.generate(
model="openai/gpt-5.4-image-2",
prompt="A minimalist product photo of a ceramic mug on a wooden table",
n=1,
extra_body={"aspect_ratio": "1:1"},
)
open("image.png", "wb").write(base64.b64decode(result.data[0].b64_json))
Les paramètres que le SDK ne connaît pas (aspect_ratio, provider, models, reasoning) vont dans extra_body.
Voix et transcription
audio = client.audio.speech.create(
model="openai/gpt-4o-mini-tts",
input="Hello from api14!",
voice="alloy",
)
audio.write_to_file("speech.mp3")
text = client.audio.transcriptions.create(
model="openai/whisper-1",
file=open("speech.mp3", "rb"),
)
print(text.text)
Erreurs
import openai
try:
client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[{"role": "user", "content": "Hi"}],
)
except openai.APIStatusError as e:
if e.status_code == 402:
print("Balance too low, add funds:", e.code) # insufficient_balance
elif e.status_code == 429:
print("Retry after", e.response.headers.get("retry-after"), "s:", e.code) # rate_limited
else:
raise
Voir Erreurs.
Délais d'attente et nouvelles tentatives
Par défaut, le SDK réessaie deux fois les erreurs de connexion, 408, 409, 429 et 5xx avec un backoff exponentiel, en respectant Retry-After. Le délai par défaut est de 10 minutes. Configurez les deux sur le client, ou par appel avec with_options :
import httpx
client = OpenAI(
base_url="https://api14.com/api/v1",
api_key=os.environ["API14_API_KEY"],
timeout=httpx.Timeout(60.0, connect=5.0),
max_retries=4,
)
client.with_options(timeout=300, max_retries=0).chat.completions.create(...)
Réessayer n'aide pas face à daily_limit_reached ou insufficient_balance ; arrêtez-vous et alertez plutôt. Voir Limites de débit.
Toutes les capacités
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api14.com/api/v1",
apiKey: process.env.API14_API_KEY,
});
const result = await client.chat.completions.create({
"model": "openai/gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Explain vector databases in two sentences."
}
]
});
console.log(result.choices[0].message.content);