Google GenAI SDK
MarkdownFormato nativo de Gemini: SDK Google GenAI para Python y JavaScript y solicitudes REST directas.
Guía completa
Instalación
pip install google-genainpm install @google/genaiConexión
La URL es https://api.ailoot.ai sin /v1beta: el SDK construye la ruta /v1beta/models/<modelo>:generateContent automáticamente. En Python, la URL se configura mediante HttpOptions(base_url=…) y en JavaScript, mediante httpOptions.baseUrl. El SDK envía la clave en la cabecera x-goog-api-key.
from google import genai
from google.genai import types
import os
client = genai.Client(
api_key=os.environ["AILOOT_API_KEY"],
http_options=types.HttpOptions(base_url="https://api.ailoot.ai"), # sin /v1beta
)
resp = client.models.generate_content(
model="gemini-3.8-flash",
contents="Inventa tres nombres para una cafetería.",
)
print(resp.text)import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.AILOOT_API_KEY,
httpOptions: { baseUrl: "https://api.ailoot.ai" }, // sin /v1beta
});
const resp = await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Inventa tres nombres para una cafetería.",
});
console.log(resp.text);curl "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $AILOOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "Inventa tres nombres para una cafetería."}]}
]
}' Datos que puedes enviar
- Campos de nivel superior:
contents,systemInstruction,generationConfig,safetySettings,toolsytoolConfig. generationConfigadmitetemperature,topP,topK,maxOutputTokens,thinkingConfig,responseMimeType(text/plainoapplication/json),responseSchemaoresponseJsonSchema(objeto JSON),stopSequences(array de cadenas),candidateCount: 1, unseedde tipo entero, y los valores numéricospresencePenaltyyfrequencyPenalty. Los rangos válidos y las funciones disponibles dependen del modelo concreto; para obtener una respuesta JSON, elige un único formato de esquema compatible yapplication/json. En los modelos de texto,responseModalitiessolo admite["TEXT"].safetySettingses un array de objetos concategory,thresholdy el campo opcionalmethod; elige los valores según la documentación del modelo concreto.- En los modelos Gemini que admiten el tipo de entrada correspondiente,
parts[].inlineDatacontienemimeTypey datos base64 no vacíos; el PDF debe ser un archivo PDF real.fileDatacontiene una dirección públicahttpsenfileUriy el tipo MIME del archivo. En YouTube se puede omitir el tipo MIME.http, las direcciones privadas,gs://y los objetos de Google Files API no se admiten, tampoco la carga mediante Google Files API. En los vídeos se puede añadirvideoMetadata:startOffset/endOffsetcomo cadenas en segundos (por ejemplo,1.5s) yfpsdebe ser mayor que 0 y no superar 24. El tamaño del cuerpo, el contexto, la entrada admitida y el límite de respuesta se validan según el modelo y el formato. - Las funciones del cliente
functionDeclarationslas ejecuta tu aplicación. Los modelos de texto también admiten{"googleSearch": {}}y{"urlContext": {}}, por separado o juntos en el arraytools. Ni Google Search ni URL context se pueden combinar confunctionDeclarationsen una misma solicitud. Para generar imágenes solo se admiten funciones del cliente. No se admiten otras herramientas integradas ni caché explícita. Search/URL context pueden requerir una reserva por el límite completo de entrada; los valores reales detoolUsePromptTokenCountse contabilizan como tokens de entrada. - Si el modelo no admite un campo, un adjunto o una combinación de herramientas, la solicitud se rechaza antes de reservar saldo y no se cobra nada. Se devuelve HTTP
400constatusINVALID_ARGUMENTy la claseinvalid_request(enErrorInfo.reason—INVALID_REQUEST). Un JSON no válido, errores en los parámetros de ruta y otros fallos de validación también devuelven400; lee el mensaje de error y el Request ID. Las capacidades dependen del modelo: consulta sus formatos y entradas en el catálogo.
| Entrada | Tipos MIME admitidos |
|---|---|
| Imágenes inline | image/png, image/jpeg, image/webp |
| Documentos | application/pdf; text/plain, text/html, text/css, text/csv, text/xml, text/rtf, text/markdown, text/javascript, application/x-javascript, text/x-python, application/x-python |
| Audio | audio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac |
| Vídeo | video/mp4, video/mpeg, video/mov, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp |
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Un solo envío. Tras un tiempo de espera agotado, consulta el Request ID en tu historial de uso antes de reintentar.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
import base64, pathlib, sys
# Proporciona un archivo local real de PDF, audio o vídeo y su tipo MIME compatible.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
{"text": "Describe brevemente el contenido del archivo."},
{"inlineData": {"mimeType": mime,
"data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Adjunto alternativo: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Para una URL real de YouTube: {"fileData": {"fileUri": youtube_url}}Ciclo completo de una función
Envía la declaración, recibe functionCall, ejecuta tu función, devuelve functionResponse y solicita la siguiente respuesta. Conserva todo el content del modelo, incluido thoughtSignature; no crees la firma por tu cuenta.
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Un solo envío. Tras un tiempo de espera agotado, consulta el Request ID en tu historial de uso antes de reintentar.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
tools = [{"functionDeclarations": [{
"name": "multiply", "description": "Multiplicar dos números",
"parameters": {"type": "object", "properties": {
"a": {"type": "number"}, "b": {"type": "number"}},
"required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Multiplica 7 por 8 con la función"}]}]
for turn in range(4): # Limita el bucle de herramientas; no vuelvas a enviar una solicitud cuyo resultado no esté claro.
reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
content = reply["candidates"][0]["content"]
contents.append(content) # Conserva TODAS las partes originales y thoughtSignature sin cambios.
results = []
for part in content.get("parts", []):
call = part.get("functionCall")
if not call:
continue
if call["name"] != "multiply":
raise ValueError("Unexpected function")
args = call["args"]
result = {"name": call["name"], "response": {"value": args["a"] * args["b"]}}
if "id" in call:
result["id"] = call["id"]
results.append({"functionResponse": result})
if not results:
print(content)
break
contents.append({"role": "user", "parts": results})
else:
raise RuntimeError("Tool loop limit reached")Respuesta en streaming
for chunk in client.models.generate_content_stream(
model="gemini-3.8-flash",
contents="Describe una puesta de sol sobre el mar",
):
print(chunk.text, end="", flush=True)curl -N "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:streamGenerateContent?alt=sse" \
-H "x-goog-api-key: $AILOOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contents": [{"role": "user", "parts": [{"text": "Describe una puesta de sol sobre el mar"}]}]}' Modelos disponibles
Hay 27 identificadores disponibles en formato Gemini: gemini-3.8-flash, gemini-3.1-pro, gemini-pro-agent, gemini-3.8-flash-tiered, gemini-3.8-flash-medium, gemini-3.8-flash-low, gemini-3.8-flash-high, gemini-3.7-flash, gemini-3.7-flash-tiered, gemini-3.7-flash-medium, gemini-3.7-flash-low, gemini-3.7-flash-high, gemini-3.6-flash, gemini-3.6-flash-tiered, gemini-3.6-flash-medium, gemini-3.6-flash-low, gemini-3.6-flash-high, gemini-3.5-flash-lite, gemini-3.1-pro-preview, gemini-3.1-pro-low, gemini-3.1-pro-high, gemini-3.1-flash-lite, gemini-3-flash, gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-thinking, gemini-2.5-flash-lite.
Los modelos Gemini también están disponibles en Anthropic Messages, lo que resulta práctico para clientes que solo admiten ese formato: Anthropic SDK.