zibloh-ai
SDK Python del router de IA de Zibloh. Tiers públicos basic / medium / premium / eu.
Zibloh tiene un solo endpoint de trabajo, POST /request, para chat, embeddings y OCR: el SDK es un cliente fino sobre httpx con un método por endpoint. El cuerpo y la respuesta son OpenAI-compatibles, pero el SDK oficial de openai no sirve contra Zibloh porque apunta a /chat/completions y /embeddings, que no existen aquí.
Instalación
pip install zibloh-ai
Uso
from zibloh_ai import Zibloh
client = Zibloh(api_key="zbl_...") # o variable de entorno ZIBLOH_API_KEY
resp = client.request(
model="premium", # basic | medium | premium | eu
messages=[{"role": "user", "content": "Hola, ¿qué tal?"}],
)
print(resp["choices"][0]["message"]["content"])
Las respuestas son dict con la forma de OpenAI. Cualquier parámetro extra
(temperature, max_tokens, tools, response_format…) se pasa tal cual.
Streaming
for chunk in client.stream(model="medium", messages=[{"role": "user", "content": "Un chiste"}]):
print(chunk["choices"][0]["delta"].get("content", ""), end="")
Un corte a mitad de stream se convierte en ZiblohError en vez de pasar inadvertido.
Embeddings
Mismo método, mismo endpoint: cambia el cuerpo.
emb = client.request(model="basic", input="texto a vectorizar")
print(emb["data"][0]["embedding"][:5])
Tiers disponibles en embeddings: basic y eu.
OCR de documentos
Mismo método, mismo endpoint: pasa document en vez de messages. Acepta una URL o un data URI
base64 (para un fichero local, sin multipart):
import base64, pathlib
pdf = base64.b64encode(pathlib.Path("factura.pdf").read_bytes()).decode()
res = client.request(
model="eu",
document={"type": "document_url", "document_url": f"data:application/pdf;base64,{pdf}"},
)
print(res["pages"][0]["markdown"])
print(res["usage_info"]["pages_processed"]) # hojas que se te facturan
OCR y extracción de campos en una sola llamada: con document_annotation_format (un JSON
schema) y/o document_annotation_prompt, la respuesta trae además document_annotation con los
campos ya extraídos, sin un segundo paso de chat.
res = client.request(
model="eu",
document={"type": "document_url", "document_url": "https://…/factura.pdf"},
document_annotation_prompt="Extrae número de factura, NIF del emisor y total.",
table_format="markdown",
)
Límites: 50 MB por fichero (más → 413) y 1000 páginas; PDF/PPTX/DOCX e imágenes PNG/JPEG/AVIF. No hay subida multipart: el fichero va en el JSON. Para documentos grandes, pasa una URL prefirmada de S3 en vez de base64 — el fichero no atraviesa el router y evitas tanto el 33 % que infla el base64 como el timeout de 60 s del edge.
Solo el tier eu hace OCR (Mistral). Pedirlo en otro tier da un 400 explicándolo, y no hay
fallback: si el proveedor europeo falla, el error llega en claro en vez de sacar el documento de
la UE en silencio. Aquí las hojas no se declaran: se cobran las que reporte el proveedor.
Documentos en chat (PDF e imágenes)
Pasa los ficheros en files: el SDK los adjunta al último mensaje user y el gateway los manda a
cada proveedor en su formato nativo (el mismo código vale para todos los tiers):
resp = client.request(
model="premium",
messages=[{"role": "user", "content": "Extrae los datos de la factura en JSON"}],
files=["factura.pdf", "anexo.png"], # rutas, bytes o content parts ya montados
response_format={"type": "json_schema", "json_schema": {"name": "factura", "schema": SCHEMA}},
)
- Formatos: PDF, PNG, JPEG, WebP, GIF (el tipo se detecta por los bytes, no por la extensión).
- TIFF no: ningún proveedor lo acepta. Conviértelo antes a PNG (una imagen por página).
- Las hojas se cuentan solas (páginas reales del PDF, 1 por imagen): no hace falta
zibloh_pages. - Respuestas largas (muchas líneas, modelos que razonan):
request()ya pide el chat en streaming por debajo y te devuelve eldictcompleto, así que no le afecta el corte del edge a los 60 s. No hace falta cambiar nada. - Para montar el mensaje a mano:
zibloh_ai.file_part("factura.pdf")devuelve el content part.
Hojas de documento (cuota)
Si el texto sale de un documento y la petición no es de OCR (p. ej. mandas texto ya extraído a chat), declara las hojas para el metering de Zibloh:
client.request(model="eu", messages=[...], zibloh_pages=12)
Errores
from zibloh_ai import ZiblohError
try:
client.request(model="eu", messages=[...])
except ZiblohError as e:
e.status_code # 429 = cuota agotada o proveedor saturado; 502/503 = caído
e.retry_after # segundos que pide el router, si los manda
Asíncrono
import asyncio
from zibloh_ai import AsyncZibloh
async def main():
async with AsyncZibloh(api_key="zbl_...") as client:
r = await client.request(model="basic", messages=[{"role": "user", "content": "ping"}])
print(r["choices"][0]["message"]["content"])
asyncio.run(main())
Tiers
from zibloh_ai import Models
Models.BASIC # "basic" — rápido y barato
Models.MEDIUM # "medium" — equilibrado
Models.PREMIUM # "premium" — máxima calidad
Models.EU # "eu" — proveedor europeo
client.models() # los tiers que el router expone ahora mismo
Configuración
| Parámetro | Variable de entorno | Por defecto |
|---|---|---|
api_key |
ZIBLOH_API_KEY |
— (obligatorio) |
base_url |
ZIBLOH_BASE_URL |
https://ai.zibloh.com/api/v1 |
https://ai.zibloh.com/api/v1es la base URL de producción y el valor por defecto. Para dev usabase_url="https://ai.devapp.zibloh.com/api/v1"(oZIBLOH_BASE_URL) con una key creada en dev: cada entorno tiene sus propias keys, y una de prod da 401 en dev.
La API Key (zbl_...) se crea desde el panel de Zibloh y requiere el scope ai:chat, ai:embeddings y/o ai:ocr (ai:* cubre los tres).
Compatibilidad con el ecosistema OpenAI
El cuerpo y la respuesta tienen la forma de OpenAI, pero Zibloh no es un openai.OpenAI:
Zibloh solo expone POST /request, así que el SDK de openai (y las librerías que lo usan por
debajo, como LangChain o LlamaIndex) no funcionan apuntándolos a Zibloh. Usa Zibloh /
AsyncZibloh, o llama a /request directamente por HTTP.
Licencia
Apache-2.0 (el texto completo va en el paquete, fichero LICENSE).
Metadata
Release files for zibloh-ai 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zibloh_ai-0.2.0.tar.gz | 19.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zibloh_ai-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.5 kB
Release files / zibloh_ai-0.2.0.tar.gz
| Download URL | zibloh_ai-0.2.0.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
364ee607c04bac7478ac9e4934518fddfbc21ed7d99a9df7b4356bdcc40c1430
|
|
BLAKE2b-256 checksum How to use checksums |
c0cd9b7da4d50ee6204d1186fa3c17be714e30583e99401c28423c8f42f8b0eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / zibloh_ai-0.2.0-py3-none-any.whl
| Download URL | zibloh_ai-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
20e58686000a040a421da2aad236760fe806ea33758e7994555182593bb63353
|
|
BLAKE2b-256 checksum How to use checksums |
a89e925e85a153288dfbe2a7d27d6bd9c37f765817484c2da0edf3b69baf6b6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log