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.

En esta página
  1. Instalar
  2. Python
  3. TypeScript
  4. Cómo se llaman los métodos
  5. Errores
  6. Cuando un método no alcanza

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.py junto a tu código. Solo usa la biblioteca estándar: no hay paquete que instalar.
TypeScript / JavaScript
Copia stockai-client.ts a tu proyecto. Usa fetch, 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 es https://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 } })