Usamos cookies. Las cookies y el almacenamiento del navegador mantienen tu sesión iniciada y recuerdan tus preferencias. Con tu permiso, también medimos cómo se usa el sitio. Puedes en cualquier momento. Consulta nuestra política de cookies.

Python

Guías de SDK

Python

Usa el paquete oficial openai de Python con api14: configura base_url y api_key, chat, streaming, herramientas, imágenes, voz, errores y reintentos.

Usa el paquete oficial de Python openai con api14. Establece base_url y api_key; usa cualquier id de modelo (por ejemplo openai/gpt-5-mini) como model.

Instalación

pip install openai
export API14_API_KEY="sk-api14-..."

Configuración

from openai import OpenAI
import os

client = OpenAI(
    base_url="https://api14.com/api/v1",
    api_key=os.environ["API14_API_KEY"],
)

También hay un cliente asíncrono: from openai import AsyncOpenAI acepta los mismos argumentos. Úsalo cuando lances muchas peticiones a la vez, por ejemplo en un servidor web o en un trabajo por lotes:

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())

Mantén la concurrencia por debajo del límite de peticiones por minuto de tu plan. Consulta Guía: procesamiento por lotes.

Sin argumentos, OpenAI() lee OPENAI_BASE_URL y OPENAI_API_KEY, así que puedes apuntar una aplicación existente a api14 solo desde el entorno:

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="")

Consulta Streaming.

Llamadas a herramientas

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)  # tu función
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

print(msg.content)

Consulta Llamadas a herramientas.

Salida estructurada

client.chat.completions.parse convierte un modelo de Pydantic en un JSON Schema estricto y devuelve el objeto analizado. Requiere una versión reciente de openai; las versiones 1.x anteriores lo exponen como client.beta.chat.completions.parse. Usa un modelo cuyo supported_parameters incluya structured_outputs o 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')

Consulta Salidas estructuradas.

Entrada de imagen

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}"}},
        ],
    }],
)

Una URL pública https:// también funciona. Consulta Visión y archivos.

Imágenes

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))

Los parámetros que el SDK no conoce (aspect_ratio, provider, models, reasoning) van en extra_body.

Voz y transcripción

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)

Errores

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

Consulta Errores.

Tiempos de espera y reintentos

Por defecto, el SDK reintenta dos veces los errores de conexión, 408, 409, 429 y 5xx con retroceso exponencial, respetando Retry-After. El tiempo de espera por defecto es de 10 minutos. Configura ambos en el cliente, o por llamada con 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(...)

Reintentar no ayuda con daily_limit_reached ni con insufficient_balance; detén el proceso y avisa. Consulta Límites de tasa.

Todas las capacidades

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);