Kamiwaza Python SDK
Python client library for interacting with the Kamiwaza AI Platform. This SDK provides a type-safe interface to all Kamiwaza API endpoints with built-in authentication, error handling, and resource management.
Installation
pip install kamiwaza-sdk
Naming note: Install the package as
kamiwaza-sdk, but import it askamiwaza_sdk. A deprecatedkamiwaza_clientalias remains for older snippets, though new code should preferkamiwaza_sdk.
Version compatibility: This SDK (version 0.5.1+) is incompatible with Kamiwaza versions before 0.5.1. Please ensure you're using the latest version of Kamiwaza.
Python SDK Usage
from kamiwaza_sdk import KamiwazaClient
from kamiwaza_sdk.authentication import UserPasswordAuthenticator
from kamiwaza_sdk.schemas.auth import PATCreate
client = KamiwazaClient("https://localhost/api")
# Option 1 (recommended): Personal Access Token
# export KAMIWAZA_API_KEY=<your-pat>
# client automatically loads the token and reuses it for every request.
# Option 2: bootstrap with username/password to mint a PAT
client.authenticator = UserPasswordAuthenticator("admin", "kamiwaza", client.auth)
pat = client.auth.create_pat(PATCreate(name="local-bootstrap")).token
print("Save this token:", pat)
Workroom-scoped automation
PAT/API-key clients should scope automation per request instead of calling
workrooms.enter(), which is reserved for real selected-session binding. Use a
local scoped client when a block of SDK calls should target one workroom:
with client.workroom_scope(workroom_id) as scoped:
scoped.context.create_vectordb(name="project-vdb", engine="milvus")
workroom_scope() returns a new client that adds the explicit workroom scope
header to its requests. It does not mutate the parent client or server-side
selected-session state. It is not a client-side security boundary; the server
must still authorize the caller for the requested workroom on every request.
Federation walkthrough (kamiwaza-mesh-v1.0.0)
Available in kamiwaza-sdk 1.0.0+ under the new top-level
kamiwazanamespace, distinct from the legacykamiwaza_sdknamespace above. See the design's §4.2.11 for the full surface.
The new kamiwaza namespace ships the federation-aware client. The
eight-step demo author's setup.py flow uses only SDK calls — no
kubectl exec, no manual SQL, no Keycloak admin REST:
- Pair LYRA with ORION —
kz.federations.pair(...) - Seed personas —
kz.subjects.upsert(...)(replaces the v0.1.x two-phase KC recipe — see authoring-guide §6) - Bind the cluster execution gate —
kz.cluster.set_execution_gate(...)(replaces thekubectl execrecipe — see authoring-guide §9.1) - Register the dataset —
kz.datasets.create(...) - Bind the dataset's attribute gate —
kz.datasets.set_gate(...) - Allowlist the brokered user + grant viewer —
kz.federations["ORION"].users.add(...)pluskz.subjects.grants("user").create(...) - Submit the federated job —
kz.jobs.run(...) - Observe the audit trail —
kz.cluster.operations()/ receiver-sidegate_binding{,_set,clear}+subject_upsertaudit events
Configure the client
import os
from kamiwaza import Kamiwaza
# Environment-driven config (recommended)
os.environ.setdefault("KAMIWAZA_BASE_URL", "https://lyra.kamiwaza.test")
os.environ.setdefault("KAMIWAZA_TOKEN", "<personal-access-token>")
kz = Kamiwaza.from_env()
# Or pass explicit values
kz = Kamiwaza(
base_url="https://lyra.kamiwaza.test",
token="<personal-access-token>",
)
# Use as a context manager so the underlying httpx transport is
# released cleanly:
with Kamiwaza.from_env() as kz:
... # walkthrough below
Step 1 — Pair LYRA with ORION
The initiator drives the handshake. The receiver only needs the PSK propagated through DataHub plus its admin baseline ReBAC tuple (install-dev.sh seeds those automatically).
fed = kz.federations.pair(
name="ORION",
role="initiator",
remote_url="https://orion.kamiwaza.test",
remote_admin_token="<orion-admin-pat>", # initiator-only
)
print(fed.id, fed.status) # e.g. fed-orion-… PAIRED
If DataHub PSK propagation is mid-flight when the request lands on
the receiver, the SDK retries with exponential backoff until the
server's structured 503 (detail.reason == "psk_propagation_timeout")
times out the budget — see kamiwaza.exceptions.FederationPairTimeoutError.
Step 2 — Declare the attribute vocabulary, then seed personas (M3 + M3.1)
Replaces the v0.1.x two-phase Keycloak admin recipe (see
authoring-a-federated-demo.md §6). Two sub-steps:
Step 2a — Declare the realm's attribute vocabulary (M3.1, v0.3.6).
Every attribute name a subject can hold must be declared in the realm
BEFORE kz.subjects.upsert(...) writes it. Keycloak's realm default
unmanagedAttributePolicy=None silently drops attribute writes for
undeclared names — the M3.1 declared-vocabulary surface converts that
silent drop into a 400 with structured remediation, so unknown names
fail loudly at upsert time instead of returning success with empty
attributes.
kz.cluster.declare_attribute("clearance", type="string")
kz.cluster.declare_attribute("country", type="string")
kz.cluster.declare_attribute("programs", type="string[]") # multivalued
declare_attribute is idempotent on identical shape — safe to re-run
during demo setup. Shape change on a declared-state attribute returns
400 shape_change_on_declared; deprecate + withdraw first to retire
the old shape. See kz.cluster.list_attributes() to inspect the
current vocabulary, and kz.cluster.deprecate_attribute(name) /
kz.cluster.withdraw_attribute(name, force=True) for retirement.
For PII-grade attributes the gate consumes via the mesh-envelope
user_attrs channel (not as a JWT claim), pass sensitive=True:
kz.cluster.declare_attribute("ssn_last4", type="string", sensitive=True)
For attributes attested by a peer cluster's brokered-user provisioning
(rather than set by local admin), pass authority="mesh_peer" —
local admin attempts to set these on local users return 400
wrong_authority_for_subject. Defaults (sensitive=False,
authority="local_admin") match the demo flow's normal case.
Step 2b — Seed personas. The single PUT writes attributes in one round-trip, infers multivalued KC entries for list-shaped values, and rolls back attribute deltas on partial failure (T3.4).
cdr_baker = kz.subjects.upsert(
"cdr-baker",
attributes={
"clearance": "TS",
"country": "USA",
"programs": ["IRIS", "ARGOS"], # list → multivalued KC attribute
},
password="cdr-baker",
)
print(cdr_baker.id, cdr_baker.attributes["clearance"]) # kc-uuid TS
Audit emits subject_upsert{outcome=success} on the receiver. A
partial-failure rollback emits subject_upsert_rollback{outcome=...}
so operators can spot drift cases in logs (T3.7). Attempting upsert
with an undeclared attribute name returns 400 attribute_not_registered
with the undeclared names enumerated and remediation text pointing
back at declare_attribute(...).
Step 3 — Bind the cluster execution gate (M3)
Replaces the kubectl exec ... RuntimeConfig().set_config(...) recipe
(see authoring-a-federated-demo.md §9.1). The PUT validates the
classpath is an ExecutionGate subclass and validates config against
the gate's config_schema() before persisting (T2.6 jsonschema).
binding = kz.cluster.set_execution_gate(
type="kamiwaza.services.authz.gates.default_gates.AllowAllExecutionGate",
# config={} omitted — AllowAllExecutionGate declares no config_schema()
)
print(binding.gate_name, binding.kind) # allow_all_execution_gate execution
Without an active binding, mesh job submission fails with 403 no_execution_gate_configured_for_mesh. The SDK surfaces wrong-kind
attempts (binding an AttributeGate as an execution gate) as
KamiwazaError with status 400.
Step 4 — Register the dataset (M3)
conjunctions = kz.datasets.create(
name="conjunctions",
platform="postgres",
environment="PROD",
properties={
"connection_secret_urn": "urn:li:secret:postgres-conjunctions",
"table": "public.conjunctions",
},
)
print(conjunctions.urn) # urn:li:dataset:(postgres,conjunctions,PROD)
Step 5 — Bind the dataset's attribute gate (M3)
ds_binding = kz.datasets.set_gate(
conjunctions.urn,
type="kamiwaza_extensions.classified_conjunction_gate.ClassifiedConjunctionGate",
config={
"classification_field": "classification",
"releasable_to_field": "releasable_to",
"program_compartment_field": "program_compartment",
},
)
print(ds_binding.dataset_urn, ds_binding.gate_name)
The server verifies the classpath is an AttributeGate (wrong-kind →
400) and that config matches the gate's config_schema() (mismatch
→ 400 schema_validation_failed). Owner-on-dataset ReBAC enforces
that only the dataset's owner can rebind the gate (T2.5 follow-up).
Step 6 — Allowlist the brokered user + grant viewer (M3)
# Receiver-side allowlist (same as WS-M1):
kz.federations["ORION"].users.add(
external_id="cdr-baker@lyra-cluster-uuid",
initial_tuples=[
{
"subject": "user:cdr-baker@lyra-cluster-uuid",
"relation": "viewer",
"object": "cluster:ORION",
},
],
)
# Then attach a ReBAC viewer relation on the dataset (M3 subjects.grants):
kz.subjects.grants("cdr-baker").create(
object_namespace="dataset",
object_id=conjunctions.urn,
relation="viewer",
)
If the user isn't on the allowlist when a mesh request arrives,
ext-authz returns 403 with detail.reason == "brokered_user_not_allowlisted". The SDK surfaces that as
kamiwaza.exceptions.BrokeredUserNotAllowlistedError.
Step 7 — Submit the federated job
target_cluster is the federation name (the same name used at
pair time). Omit it to run locally on the cluster the SDK is
talking to.
result = kz.jobs.run(
target_cluster="ORION",
entrypoint="python /workdir/query.py --rows 1000",
)
print(result.status, result.audit_actor)
# SUCCEEDED cdr-baker@lyra-cluster-uuid
For longer jobs, prefer the async + poll pattern — submit_async
returns immediately and wait polls with bounded backoff until
the job reaches a terminal state:
job_id = kz.jobs.submit_async(
target_cluster="ORION",
entrypoint="python /workdir/long_query.py",
)
result = kz.jobs.wait(job_id, timeout=600)
For a governed receiver job, pass exact typed resources at submission. The server rejects the whole request if any resource or operation is not granted:
from kamiwaza_sdk import DelegatedAccess, DatasetDelegatedAccess
job_id = kz.jobs.submit_async(
target_cluster="ORION",
entrypoint="python summarize.py",
timeout_seconds=36_000,
delegated_access=DelegatedAccess(
datasets=(
DatasetDelegatedAccess(
urn=DATASET_URN,
operations=("discover", "read", "retrieve"),
),
),
),
)
Inside that managed job, use only the private credential-agent socket. The runtime client never reads an API key, user token, refresh token, or public base URL; capability renewal remains inside the agent:
from kamiwaza_sdk import JobRuntimeClient
with JobRuntimeClient.from_environment() as receiver:
granted = receiver.datasets.list_granted()
rows = receiver.retrieval.collect(dataset_urn=DATASET_URN)
answer = receiver.models.chat(
deployment_id=DEPLOYMENT_ID,
messages=[{"role": "user", "content": summarize(rows)}],
)
receiver.retrieval.stream(...) and receiver.models.stream_chat(...) expose
streaming iterators. A sidecar restart is picked up on the next operation by
re-reading and kernel-verifying the platform-owned agent identity file.
wait raises kamiwaza.exceptions.MeshJobTimeoutError when the
budget expires before a terminal state. A failed job returns a
JobResult with status="FAILED" and an error message — that's
not exceptional, that's data.
Step 8 — Observe audit
The receiver-side audit log shows the job completing as the
originating user (cdr-baker@lyra-cluster-uuid), not as a
system principal. M3 adds two more event types operators can grep for:
gate_binding{action: set|clear, kind: execution|attribute}— every PUT/DELETE on the cluster + dataset gate endpoints (T2.12).subject_upsert{,_rollback}andsubject_grant_change— every AuthzSubjects mutation (T3.7).
# Federated job audit trail
kubectl -n kamiwaza logs deployment/core-scheduler \
| grep federated_job_completed \
| jq 'select(.audit_actor)'
# M3 gate-binding + subject-management audit
kubectl -n kamiwaza logs deployment/core-scheduler \
| jq 'select(.event_type | startswith("gate_binding") or
startswith("subject_"))'
The audit_actor field is the same value kz.jobs.run(...).audit_actor
returns in step 7 — that round-trip is the demo gate's load-bearing
signal.
Recoverable long-jobs
For jobs that may take longer than ~60 seconds, use kz.jobs.run(..., recoverable=True) instead of the default. The default holds the HTTP
connection for the full job duration; FastAPI buffers the
X-Job-Id response header along with the body and only flushes both on
completion. If the connection drops mid-job, the SDK never sees the
X-Job-Id and has no handle to recover the result from.
recoverable=True flips the SDK to a submit + poll shape under the
covers:
POST /api/cluster/jobs/submitreturns thejob_idimmediately.- The SDK polls
/cluster/jobs/{id}/statuswith exponential backoff until the job reaches a terminal state. /cluster/jobs/{id}/resultfetches the final payload.
Because the job_id is in the SDK's hands from the first response, a
mid-job process crash is recoverable on a fresh SDK instance:
# Original process
job_id = kz.jobs.submit_async(
entrypoint="python query.py",
target_cluster="ORION",
timeout_seconds=600,
)
# ... persist (job_id, target_cluster) somewhere (sqlite, etc.) ...
# ... process dies ...
# Fresh process, much later
saved_job_id = load_persisted_job_id()
saved_target_cluster = "ORION"
result = kz.jobs.wait(
saved_job_id,
timeout=600,
target_cluster=saved_target_cluster,
)
The client that submitted the job remembers up to 256 recent remote handles,
so wait(job_id, ...) and cancel(job_id) on that same client do not need the
selector repeated. A new client has no such in-memory routing state.
Recommended: use recoverable=True for any job with
timeout_seconds > 60. The two-call cost (submit + poll) is amortized
over the long runtime.
Error handling cheat sheet
The SDK maps server-side error contracts to typed exceptions so
customer code can branch on the failure mode. All inherit from
kamiwaza.exceptions.KamiwazaError:
| Exception | Trigger |
|---|---|
FederationPairTimeoutError |
Receiver couldn't see the PSK before the retry budget expired. |
BrokeredUserNotAllowlistedError |
Mesh request from a user not in the receiver's allowlist. |
MeshJobTimeoutError |
kz.jobs.wait(...) budget expired before terminal state. |
MeshJobFailedError |
Job reached FAILED state and the caller asked for an exception. |
NativeRealmRequiredError |
Operation requires a native (non-brokered) realm user. |
KamiwazaError 403 ...read-only... |
Write aimed at the Global Workroom (shared read-only catalog) — by design; write to a workroom you own instead. See Context Service. |
KamiwazaError (catch-all) |
Other 4xx/5xx; check .status_code and .body for details. |
from kamiwaza import KamiwazaError
from kamiwaza.exceptions import FederationPairTimeoutError
try:
kz.federations.pair(name="ORION", role="initiator", remote_url=...)
except FederationPairTimeoutError as exc:
# Retriable — DataHub propagation didn't make the deadline this run.
print(f"Retry later: {exc.body!r}")
except KamiwazaError as exc:
# Catch-all for everything else.
print(f"{exc.status_code}: {exc}")
Examples
The /examples directory contains Jupyter notebooks demonstrating various use cases. To run them locally against a Kamiwaza dev cluster, install JupyterLab in your env (pip install jupyterlab ipywidgets) and run jupyter lab from examples/. Set KAMIWAZA_BASE_URL and KAMIWAZA_API_KEY in the environment before launching so the notebooks can reach your cluster.
- Model Download and Deployment - A comprehensive guide to searching, downloading, deploying, and using models with the Kamiwaza SDK
- Quick Model Deployment - Streamlined approach to download and deploy models using a single function
- Model Evaluation - How to evaluate and benchmark multiple language models for performance comparison using the streamlined
download_and_deploy_modelfunction - Structured Output - Using Kamiwaza's OpenAI-compatible interface to generate structured outputs with specific JSON schemas
- Function Calling - Demonstrates how to use function calling (tools) with Kamiwaza's OpenAI-compatible API
- Web Agent - Build an AI agent that can browse and interact with web pages
- RAG Demo - Retrieval Augmented Generation using Kamiwaza's vector database and embedding services
- App Garden and Tool Shed - Deploy containerized applications and MCP Tool servers
- Reference Chatbot App - A buildable Kamiwaza extension app that mirrors the default
kz-ext create --type appstarter
More examples coming soon!
Service Overview
| Service | Description | Documentation |
|---|---|---|
client.models |
Model management | Models Service |
client.serving |
Model deployment | Serving Service |
client.vectordb |
Vector database | VectorDB Service |
client.context |
Workroom-scoped vector DBs, ontologies, ingestion, retrieval | Context Service |
client.catalog |
Data management | Catalog Service |
client.embedding |
Text processing | Embedding Service |
client.retrieval |
Search | Retrieval Service |
client.cluster |
Infrastructure | Cluster Service |
client.lab |
Lab environments | Lab Service |
client.auth |
Security | Auth Service |
client.authz |
Authorization tuples/checks | AuthZ Service |
client.activity |
Monitoring | Activity Service |
client.openai |
OpenAI API compatible | OpenAI Service |
client.apps |
App deployment | App Service |
client.tools |
Tool servers (MCP) | Tool Service |
client.skills |
Skills Library catalog and package workflows | Skills Service |
client.ingestion |
Data ingestion | Ingestion Service |
client.enclaves |
Connectors + documents | Enclaves Service |
Auth / User Management (0.9.0)
- Base URL rule: set
base_url=https://<host>(no/authsuffix). Quick preflight:GET {base_url}/auth/ping→ 200. If you include/auth, calls will double-prefix and fail. - Admin-only: creating/resetting users requires an admin bearer.
- Auth-on semantics:
create_local_userprovisions Keycloak so the user can authenticate;reset_user_passwordupdates Keycloak only (Keycloak is authoritative). Auth-off updates the local hash only. - Roles caveat: requested realm roles must exist; otherwise create will 500 + rollback. Omit roles or use known-good roles.
- Self-signed TLS: set
--verify-ssl false(orverify_ssl=False) when needed. - A runnable smoke script lives at
scripts/fed_user_smoke.py(see script usage inside).
Integration Tests
The tests/integration suite spins up a MinIO fixture via Docker Compose and
exercises the ingestion → catalog flow using the SDK. Run it with:
pytest -m integration
Note: Retrieval checks are currently marked
xfailbecause the live deployment returns HTTP 500 while Ray-backed transport is being stabilised.
Extension Developer Tools (kz-ext)
The kz-ext CLI helps extension developers scaffold, validate, build, deploy, and debug Kamiwaza extensions.
Installation
# Install the SDK (includes extension tools)
pip install kamiwaza-sdk
# Optional extras:
pip install kamiwaza-sdk[publish] # Adds boto3 for kz-ext publish
pip install kamiwaza-sdk[convert] # Adds anthropic for kz-ext convert (OpenAI is included by default)
pip install kamiwaza-sdk[flight] # Adds PyArrow for retrieval Flight streams
pip install kamiwaza-sdk[all] # All three extras
# Verify
kz-ext --version
kz-ext has its own manifest-capability version because it can evolve on a
different cadence from the containing kamiwaza-sdk distribution. Version
0.2.0 is the first enforceable capability baseline that guarantees support
for kamiwaza.json.services.<service>.healthCheck (ENG-4832). Extension
manifests declare their required CLI range with kz_ext_version; incompatible
tooling fails before build, publish, or remote deployment.
For the Kamiwaza 1.2 release line, the distribution mapping is:
kamiwaza-sdk distribution |
bundled kz-ext capability |
validated platform range |
|---|---|---|
1.1.0 |
0.2.0 |
>=1.2.0,<1.3.0 |
The kamiwaza-v1.2.0 and release/1.2.1 SDK sources use the same extension
payload contract, so this single artifact supports both platform releases.
Quick Start
# 1. Authenticate (local dev — uses https://kamiwaza.test/api, skips SSL verify)
kz-ext login --dev
# Or specify a URL: kz-ext login https://your-instance.example.com/api
# For self-signed certs: kz-ext login --no-verify-ssl
# 2. Scaffold a new extension
mkdir my-app && cd my-app
kz-ext create --type app --name my-app
# The generated app is already a working AI starter with:
# - explicit model selection
# - a simple chat UI
# - AGENTS.md and CLAUDE.md for coding assistants
# 3. Validate the extension metadata
kz-ext validate
# 4. Run locally with Docker Compose
kz-ext dev local
# 5. Deploy to a Kamiwaza cluster (build, push, deploy — one command)
kz-ext dev
# 6. Iterate: change code, re-run (zero-downtime update via PATCH)
kz-ext dev
# 7. Inspect the running extension
kz-ext status
kz-ext logs --service backend --follow
kz-ext shell --service backend
# 8. Forward a port for direct debugging
kz-ext port-forward --service backend --port 8000
# 9. Convert an existing app to a Kamiwaza extension
kz-ext convert /path/to/existing-app
# 10. Publish to an extension catalog
kz-ext config publish-profile prod \
--registry ghcr.io/my-org \
--catalog-endpoint https://my-account.r2.cloudflarestorage.com \
--catalog-bucket extensions-prod \
--catalog-credentials aws-profile:prod
kz-ext publish --stage prod
Commands
| Command | Description |
|---|---|
kz-ext login [url] |
Authenticate with a Kamiwaza instance (default: https://kamiwaza.test/api). Supports --api-key, --name, --list, --use, --no-verify-ssl. |
kz-ext create --type <type> --name <name> |
Scaffold a new extension in the current (empty) directory. Types: app (Next.js + FastAPI), tool (FastMCP), service (minimal). |
kz-ext validate [path] |
Validate kamiwaza.json, docker-compose.yml, and clear platform-runtime incompatibilities such as privileged ports or root-only web containers. Use --json for machine-readable output. |
kz-ext dev local |
Run the extension locally via Docker Compose with Kamiwaza env vars injected. Auto-detects port conflicts and remaps to available ports. Supports --sdk-repo, --detach, and --auth (bridges the developer's identity from kz-ext login and routes loopback Kamiwaza URLs through the host gateway — see docs/extensions/cli-reference/dev-local.md). |
kz-ext dev |
Build, push, and deploy to a Kamiwaza cluster. Uses zero-downtime PATCH updates for existing extensions. Supports --no-build, --no-push, --service, --revision, --sdk-repo. |
kz-ext status |
Show deployment status: phase, per-service readiness, URL, and recent K8s events. Supports --name. |
kz-ext logs |
Stream logs from deployed extension pods. Supports --service, --follow, --tail, --name. |
kz-ext shell |
Open an interactive shell in a running extension container. Supports --service, --name. |
kz-ext port-forward |
Forward a port from a deployed pod to localhost for debugging. Supports --service, --port, --name. |
kz-ext convert <path> |
AI-powered conversion of existing apps to Kamiwaza extensions. Analyzes code, generates kamiwaza.json, and wires in SDK integration. Supports --dry-run. |
kz-ext publish --stage <profile> |
Build production images, push to registry, and publish to an S3-compatible extension catalog. Supports --dry-run, --force, --no-build, --no-push. |
kz-ext bump |
Bump extension version in kamiwaza.json. Defaults to patch. Supports --level major|minor|patch. |
kz-ext config publish-profile |
Create, list, show, or delete named publish profiles. Supports --list, --show, --delete, --repo-level. |
kz-ext doctor |
Check your development environment (Python, Docker, Compose, kubectl, connection health, runtime libs). |
Development Workflow
The typical edit-deploy-test cycle:
kz-ext devbuilds Docker images with a unique dev tag, pushes to the cluster registry, and deploys via the platform API.- On the first run, it creates a new extension (POST). On subsequent runs, it patches the existing deployment with new image tags (PATCH), triggering a Kubernetes rolling update with zero downtime.
kz-ext statusshows whether the rollout is complete, per-service readiness, and any issues (image pull failures, OOM kills, probe failures).kz-ext logsandkz-ext shellgive direct access to running pods for debugging.
No version bumps, registry builds, or manual redeploy steps required during development.
Publishing
When your extension is ready for release:
- Configure a publish profile with
kz-ext config publish-profile— specify a container registry and S3-compatible catalog endpoint. - Bump the version with
kz-ext bump(orkz-ext bump --level minor). kz-ext publish --stage prodbuilds production-tagged images, pushes to the profile's registry, and publishes to the catalog.kz-ext publish --stage prod --dry-runpreviews what would happen without making changes.
Publish profiles support multiple environments (dev/staging/prod) and CI via env var overrides (KZ_PUBLISH_REGISTRY, KZ_PUBLISH_CATALOG_ENDPOINT, etc.).
Converting Existing Apps
kz-ext convert /path/to/existing-app
Uses an AI agent to analyze existing Dockerfiles, compose files, and size-capped source context, then generates kamiwaza.json and wires in SDK integration (health endpoints, auth middleware, runtime libraries). Common secret-bearing files such as .env, credential JSON files, and private key files are excluded from that context. The conversion flow now validates generated output against the Kamiwaza runtime contract as well, including non-root execution, unprivileged HTTP ports, and read-only-root-filesystem-friendly web wrappers. All changes are git-tracked — review with git diff.
Optionally uses OPENAI_API_KEY (or ANTHROPIC_API_KEY) for AI-powered conversion. Falls back to basic kamiwaza.json generation without an API key. Set OPENAI_BASE_URL to use any OpenAI-compatible provider (Kamiwaza, vLLM, Ollama, etc.). Set KZ_PUBLISH_DOCKER_TOKEN or DOCKER_TOKEN for registry auth during publish.
Extension Types
- App (
--type app): Full-stack extension with Next.js frontend and FastAPI backend, pre-wired with@kamiwaza-ai/extensions-libandkamiwaza-extensions-lib. - The app starter includes a working authenticated chat flow so developers can customize a real extension instead of starting from a status dashboard.
- Tool (
--type tool): MCP tool server using FastMCP withkamiwaza-extensions-lib. - Service (
--type service): Minimal containerized service.
Local SDK Development (--sdk-repo)
When iterating on the runtime libraries themselves (kamiwaza-extensions-lib or @kamiwaza-ai/extensions-lib), use --sdk-repo to override the published packages with your local SDK source:
# Via CLI flag
kz-ext dev local --sdk-repo ~/repos/kamiwaza-sdk
# Or via repo-local config (gitignored)
mkdir -p .kz-ext
cat > .kz-ext/local.yaml << 'EOF'
sdk_repo: /Users/you/repos/kamiwaza-sdk
runtime_libs:
python: local # override Python lib (default: local when sdk_repo is set)
typescript: local # override TypeScript lib
build_typescript: true # auto-build TS package if dist/ is missing or stale
EOF
kz-ext dev local # reads .kz-ext/local.yaml automatically
How it works:
kz-ext dev local --sdk-repo: Mounts the SDK repo into containers at runtime and overrides the published packages with local source (copies Python lib files over installed package, npm pack + install for TypeScript).kz-ext dev --sdk-repo: Bakes the local runtime libraries into Docker images at build time using BuildKit additional build contexts. The resulting images contain your local lib code and are pushed to the cluster normally.kz-ext doctor: Validates the SDK override configuration — checks that the SDK repo exists, Python and TypeScript libs are present, anddist/is built.
The override is ephemeral — it never modifies your extension repo's docker-compose.yml or Dockerfiles.
Port Auto-Detection
kz-ext dev local automatically detects occupied ports and remaps to the next available:
$ kz-ext dev local
Port 3000 in use — remapping frontend to 3001
Port 8000 in use — remapping backend to 8001
frontend: http://localhost:3001
backend: http://localhost:8001
This lets you run multiple extensions simultaneously without port conflicts.
Multi-Connection Support
# Add named connections
kz-ext login https://prod.example.com/api --name prod
kz-ext login https://staging.example.com/api --name staging
# List connections
kz-ext login --list
# Switch active connection
kz-ext login --use staging
The Kamiwaza SDK is actively being developed with new features, examples, and documentation being added regularly. Stay tuned for updates including additional example notebooks, enhanced documentation, and expanded functionality across all services.
Metadata
Release files for kamiwaza-sdk 1.1.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 | |
|---|---|---|---|
| kamiwaza_sdk-1.1.0.tar.gz | 508.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kamiwaza_sdk-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.1 MB
Release files / kamiwaza_sdk-1.1.0.tar.gz
| Download URL | kamiwaza_sdk-1.1.0.tar.gz |
|---|---|
| Size | 508.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
07d7f1caea348bdeeeffa5c68d09822d04e67432f8347f181fe19d1de60642fa
|
|
BLAKE2b-256 checksum How to use checksums |
24fec6bc967536abeeea60ac71962e076779d06349c5aef3abe81e5f6fdc7419
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / kamiwaza_sdk-1.1.0-py3-none-any.whl
| Download URL | kamiwaza_sdk-1.1.0-py3-none-any.whl |
|---|---|
| Size | 576.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
49bc45def48de66fc39fcb782e5b859d6e236c5360b88265522e6209139f1fcd
|
|
BLAKE2b-256 checksum How to use checksums |
d684c97d99c2e2a6dbfc828969640e3d97737bdf643e7023964319a7ac9de678
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|