Clientes para Python y TypeScript
Dos clientes de un solo archivo, sin dependencias, generados desde la propia API: cómo instalarlos, crear el cliente, llamar y manejar los errores.
Los clientes están en el código fuente de StockAI: sdk/python/stockai_client.py y sdk/typescript/stockai-client.ts. Se generan desde la descripción de la API, con un método por endpoint, y una prueba falla si se desfasan de ella.
Instalar
- Python
- Copia
stockai_client.pyjunto a tu código. Solo usa la biblioteca estándar: no hay paquete que instalar. - TypeScript / JavaScript
- Copia
stockai-client.tsa tu proyecto. Usafetch, así que funciona en Node 18+, Deno, Bun y navegadores.
Python
# Copy sdk/python/stockai_client.py next to your code. Standard library only.
from stockai_client import StockAI, StockAIError
api = StockAI("sk_live_...") # base_url="https://app.stockai.es" by default
# api = StockAI(key, base_url="https://stockai.yourcompany.com", timeout=60.0)
planning = api.get_planning()["data"] # every call returns the full envelope
session = planning["active_session_id"]
urgent = api.get_inventory_status(signal="PEDIR_YA")["data"]["items"]
try:
api.post_inventory_log_po(
session_id=session,
idempotency_key="6f1c2a0e-1b7d-4c55-9a51-3f0f4e0b8d21",
body={"items": [{"sku": "SKU-001", "recommended_qty": 120,
"final_qty": 100, "status": "modified"}]},
)
except StockAIError as e:
print(e.status, e.error_code, e.error_params, e.retry_after)
# A file upload
with open("sales.csv", "rb") as f:
api.post_data_sources_source_id_file("ds_66dede3ccf04",
files={"file": ("sales.csv", f.read())})TypeScript
// Copy sdk/typescript/stockai-client.ts into your project. No dependencies (fetch only).
import { StockAI, StockAIError } from './stockai-client'
const api = new StockAI(process.env.STOCKAI_KEY!) // or new StockAI(key, 'https://stockai.yourcompany.com')
const planning = (await api.get_planning()).data
const urgent = (await api.get_inventory_status({ signal: 'PEDIR_YA' })).data.items
try {
await api.post_inventory_log_po({
session_id: planning.active_session_id,
'Idempotency-Key': crypto.randomUUID(),
body: { items: [{ sku: 'SKU-001', recommended_qty: 120, final_qty: 100, status: 'modified' }] },
})
} catch (e) {
if (e instanceof StockAIError) console.log(e.status, e.errorCode, e.errorParams, e.retryAfter)
}Cómo se llaman los métodos
- El nombre es el método HTTP más la ruta:
GET /inventory/status→get_inventory_status;POST /purchase-orders/{po_log_id}/erp-reference→post_purchase_orders_po_log_id_erp_reference. Es el mismo id que la referencia de /desarrolladores. - Los parámetros de ruta van primero, posicionales; los de consulta, con nombre (Python) o en un objeto (TypeScript).
- Cada llamada devuelve el sobre completo tal como lo mandó la API (
success,data,meta); una descarga de archivo devuelve los bytes. - El constructor rechaza una llave que no empiece con
sk_. La URL por defecto eshttps://app.stockai.es; si tu instalación es propia, pásala como segundo argumento.
Errores
Una llamada rechazada lanza StockAIError con el código HTTP (status), el error_code, los error_params y, cuando la API lo mandó, retry_after (Python) / retryAfter (TypeScript) en segundos. Los clientes no reintentan solos: aplica tú las reglas de Límites y errores.
Cuando un método no alcanza
Los dos clientes tienen un request(method, path, ...) genérico. Úsalo para las rutas que leen el cuerpo crudo, como enviar filas a un perfil de sincronización o aplicar un documento de perfil: los métodos generados post_inventory_sync_profiles_profile_id_ingest y post_inventory_sync_profiles_apply no aceptan cuerpo.
# Python: push rows through the generic request() (the generated ingest method sends no body)
api.request("POST", f"/inventory-sync/profiles/{profile_id}/ingest",
body={"batch_id": "night-2026-10-22", "rows": rows})
// TypeScript
await api.request('POST', '/inventory-sync/profiles/' + profileId + '/ingest',
{ body: { batch_id: 'night-2026-10-22', rows } })