ES ▾

URL base personalizada del SDK de Python de OpenAI: configuración y correcciones

Un cable movido de un socket de servidor a otro, mostrando un cambio de URL base para un SDK

Los SDKs de OpenAI te permiten sobrescribir el endpoint con un solo argumento. Esta página muestra la configuración exacta de la URL base personalizada del SDK de Python de OpenAI para esta API, además de la equivalente en Node, streaming y los errores que causan la mayoría de los fallos en las primeras llamadas.

Última actualización

Resumen

  • Establece base_url a https://api.apicompatible.com/v1 y pasa tu clave como api_key; nada más en tu código tiene que cambiar.
  • El id del modelo es uncensored. Dejar un nombre de modelo antiguo en su lugar es la razón más común por la que falla la primera llamada.
  • El streaming funciona con stream=True, y cada petición con streaming ocupa una de tus ranuras de concurrencia hasta que finalice.
  • Las variables de entorno te permiten cambiar endpoints sin tocar el código.

La respuesta corta

Crea el cliente con dos argumentos, base_url y api_key, y sigue usando los mismos métodos que ya conoces. La URL base para esta API es https://api.apicompatible.com/v1, el id del modelo es uncensored, y la autenticación es un token bearer estándar que el SDK construye a partir de tu clave.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.apicompatible.com/v1",
    api_key="YOUR_API_KEY",
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Name three uses for a hash map."},
    ],
)

print(resp.choices[0].message.content)
print(resp.usage)

Ese es el cambio completo. El SDK añade /chat/completions a la URL base, por lo que la petición llega a POST /v1/chat/completions. Si aún no tienes una clave, la página de clave de API explica el registro y el crédito de prueba.

Establecer la URL base con variables de entorno

El SDK oficial de Python lee OPENAI_API_KEY y OPENAI_BASE_URL del entorno cuando no los pasas en el código. Eso es útil cuando la misma aplicación se ejecuta contra diferentes endpoints en desarrollo y producción, o cuando una herramienta de terceros construye el cliente para ti y no te da lugar para editar los argumentos del constructor.

export OPENAI_BASE_URL="https://api.apicompatible.com/v1"
export OPENAI_API_KEY="YOUR_API_KEY"

python - <<'EOF'
from openai import OpenAI

client = OpenAI()
r = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Say hello in five words."}],
)
print(r.choices[0].message.content)
EOF

Los argumentos explícitos ganan a las variables de entorno. Si una llamada va al host equivocado, comprueba si otra parte de tu código construye un cliente con su propio base_url, y si un cargador de .env se ejecuta antes de que tu script lea las variables.

Mantén la clave fuera del control de código fuente. Una clave en una variable de entorno o en un gestor de secretos es fácil de rotar; una clave en un archivo con cambios confirmados no lo es.

El mismo cambio en Node

El paquete de Node usa camelCase para la misma opción. Todo lo demás, incluidos los nombres de los métodos y la forma de la respuesta, coincide con lo que escribirías contra cualquier endpoint compatible con OpenAI.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.apicompatible.com/v1",
  apiKey: process.env.API_KEY,
});

const completion = await client.chat.completions.create({
  model: "uncensored",
  messages: [{ role: "user", content: "Give me a one-line commit message for a typo fix." }],
});

console.log(completion.choices[0].message.content);

Para una comprobación HTTP en crudo sin ningún SDK, esta llamada curl envía la misma petición y es útil para separar problemas del SDK de problemas de la clave:

curl https://api.apicompatible.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"uncensored","messages":[{"role":"user","content":"ping"}]}'

Streaming, asíncrono y reintentos

El streaming utiliza eventos enviados por el servidor, y el SDK los convierte en un iterador. Pasa stream=True y lee los deltas a medida que llegan. Los números de uso llegan al final del streaming, así que protege los fragmentos que no contengan texto.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.apicompatible.com/v1",
    api_key="YOUR_API_KEY",
)

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Explain idempotency in two sentences."}],
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()

El cliente asíncrono toma los mismos dos argumentos. Cambia OpenAI por AsyncOpenAI, añade await y usa async for en los streaming.

Dos límites importan cuando ejecutas más de una petición a la vez. Una clave completa permite 8 peticiones simultáneas y 300 peticiones por minuto, y una clave de prueba permite 2 y 60. Una petición con streaming mantiene su ranura de concurrencia hasta que finalice el streaming, por lo que un consumidor estancado que nunca vacía el streaming desperdicia una ranura. Por encima del límite obtienes HTTP 429 con el código de error rate_limited o concurrency. El SDK reintenta las peticiones fallidas un par de veces por defecto, y puedes cambiar eso con max_retries en el cliente. Un 429 con un encabezado Retry-After: 5 significa sobrecarga temporal, por lo que esperar cinco segundos es la respuesta correcta.

Timeouts, reutilización del cliente y depuración de lo enviado

Crea el cliente una vez y reutilízalo. Cada cliente mantiene su propio grupo de conexiones, así que construir uno nuevo para cada petición pierde tiempo y hace más difícil razonar sobre el código de streaming. Ambas opciones a continuación se establecen en el constructor y se aplican a cada llamada realizada a través de ese cliente.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.apicompatible.com/v1",
    api_key="YOUR_API_KEY",
    timeout=60.0,
    max_retries=2,
)

Las generaciones largas pueden tardar un poco, por lo que un tiempo de espera muy corto produce errores que parecen fallos del servicio. Elige un tiempo de espera que se ajuste a tu respuesta más larga esperada, y aumentalo para salidas grandes.

Cuando no puedes saber qué URL o clave usó una petición, activa el registro de depuración del SDK. Las versiones recientes del paquete de Python leen una variable de entorno OPENAI_LOG, y establecerla en debug imprime la línea de la petición y el estado de la respuesta. Consulta la documentación actual del SDK para el comportamiento exacto en tu versión, y elimina la variable después, ya que los registros pueden contener datos sensibles. El host impreso debería ser api.apicompatible.com. Si muestra algo más, una instancia de cliente diferente o una variable de entorno está sobrescribiendo tu configuración.

Un último hábito que ahorra tiempo: mantén la URL base, la clave y el id del modelo en un módulo de configuración. Cuando los tres viven en un solo lugar, cambiar endpoints se convierte en una sola edición y una sola revisión.

Errores que rompen la primera llamada

La mayoría de las primeras llamadas fallidas provienen de una lista corta de causas. Trabaja a través de ella en orden antes de sospechar del servicio.

La URL base falta /v1 o tiene una ruta fuera de lugar

El SDK añade solo el nombre del endpoint, así que la URL base debe terminar en /v1. Usar https://api.apicompatible.com sin el segmento de versión, o pegar la ruta completa /v1/chat/completions, suele producir un error de no encontrado porque la URL final termina mal. Imprime client.base_url si no estás seguro de qué resolvió el SDK.

El id del modelo sigue siendo un nombre de otro proveedor

Esta API sirve un único modelo y su id es uncensored. Un nombre de modelo dejado de una configuración anterior es una causa frecuente de errores, y es fácil de pasar por alto cuando el nombre está en un archivo de configuración en lugar del código. Busca en tu proyecto la cadena antigua.

La clave proviene del lugar equivocado

Una clave de otro proveedor no funcionará aquí, y lo inverso también es cierto. Si estableces tanto OPENAI_API_KEY como un api_key explícito, se usa el valor explícito. Comprueba cuál llegó al cliente.

Llamas a un endpoint que esta API no ofrece

La API es solo de texto. Expone /v1/chat/completions, /v1/responses y /v1/models. No hay endpoints de imagen, audio ni embeddings, ni ajuste fino, por lo que las rutas de código que los usan deben permanecer en su proveedor original. El análisis de coste y trade-off cubre cuándo tiene sentido esa división.

La carga útil es demasiado grande

El cuerpo máximo de la petición es de 8 MB. Los contextos largos están bien hasta 100.000 tokens en total para prompt más completion, pero los blobs en base64 o archivos pegados grandes pueden alcanzar el límite del cuerpo primero.

Comprobación de la conexión y tu saldo

Antes de depurar el código de la aplicación, llama a GET /v1/models. Una lista limpia significa que la clave y la URL están bien. Cada respuesta también lleva un encabezado X-Balance-USD, que te permite vigilar el gasto sin una llamada separada. Con el SDK de Python, usa with_raw_response para leer encabezados:

from openai import OpenAI

client = OpenAI(
    base_url="https://api.apicompatible.com/v1",
    api_key="YOUR_API_KEY",
)

raw = client.chat.completions.with_raw_response.create(
    model="uncensored",
    messages=[{"role": "user", "content": "ping"}],
)

print(raw.headers.get("X-Balance-USD"))
print(raw.headers.get("X-Request-Id"))
completion = raw.parse()
print(completion.choices[0].message.content)

Mantén el valor X-Request-Id cuando contactes con soporte, porque identifica la petición exacta. Las peticiones fallidas o rechazadas no se cobran, así que una mala llamada no cuesta nada. El precio es de $0.15 por cada 1M de tokens de entrada y $0.50 por cada 1M de tokens de salida del crédito prepago; la página de precios tiene los detalles y la documentación lista cada parámetro.

Preguntas frecuentes

¿Necesito un SDK especial para usar una URL base personalizada?

No. Los paquetes estándar de OpenAI para Python y Node aceptan una opción de URL base. Cambias esa opción y la clave, y mantienes tus llamadas existentes.

¿Es base_url o baseURL?

Python usa base_url y Node usa baseURL. Ambas toman el mismo valor, https://api.apicompatible.com/v1.

¿Qué nombre de modelo debo enviar?

Envía uncensored como el modelo. Esta API ejecuta un solo modelo, así que no hay nada más de qué elegir.

¿Por qué obtengo HTTP 429 cuando solo ejecuto pocas peticiones?

Una clave de prueba permite 2 peticiones simultáneas, y las conexiones de streaming abiertas cuentan para ese número hasta que finalicen. Cierra o completa las conexiones de streaming, o pasa a una clave completa para 8 peticiones simultáneas.

Obtén tu clave en segundos

Regístrate, copia el token, actualiza la URL del endpoint. Esa es toda la configuración.

Abrir cuenta