Official Python SDK for the WizChat Management API (config-as-code control plane).
Project description
wizchat-management
Official Python SDK for the WizChat Management API — the programmatic
control plane for WizChat chatbots, including the config-as-code workflow
(get_config → edit → apply_config).
The typed models in wizchat_management.models are generated from the canonical
OpenAPI 3.1 document via datamodel-code-generator
(Pydantic v2). The client is a thin httpx
wrapper — no heavy framework dependencies. It mirrors the TypeScript SDK
(@wizchat/management) one-to-one in surface and semantics.
Install
pip install wizchat-management
Requires Python 3.10+.
Authentication
Authenticate with a Management API key (wpk_live_…). It is sent on every
request as Authorization: Bearer <key>. Keys are scoped — each operation
requires specific scopes (chatbots:read, chatbots:write, mcp:*,
skills:*, security:*, domains:*, deploy, analytics:read,
documents:*, videos:*). A request with insufficient scope raises a
WizChatApiError (status == 403, code == "insufficient_scope").
import os
from wizchat_management import WizChatClient
wizchat = WizChatClient(
api_key=os.environ["WIZCHAT_API_KEY"], # wpk_live_...
# base_url defaults to https://www.wizchat.com — override for staging/self-host.
)
Quickstart
import os
from wizchat_management import WizChatClient, WizChatApiError
wizchat = WizChatClient(api_key=os.environ["WIZCHAT_API_KEY"])
try:
# 1. List your chatbots.
chatbots = wizchat.list_chatbots()
chatbot_id = chatbots[0].id
# 2. Export the current configuration as a desired-state document.
config = wizchat.get_config(chatbot_id)
# 3. Edit the document in memory (config-as-code).
core = dict(config.spec.core or {})
core["name"] = "Acme Support Bot"
config.spec.core = core
# 4. Preview the change with a dry-run — returns the reconcile plan, no writes.
plan = wizchat.apply_config(chatbot_id, config, dry_run=True)
print(plan.plan.summary) # { create, update, delete, noop }
# 5. Apply for real once the plan looks right.
result = wizchat.apply_config(chatbot_id, config)
print(result.applied)
except WizChatApiError as err:
print(f"API error {err.status} [{err.code}]: {err.message}", err.details)
finally:
wizchat.close()
WizChatClient is also a context manager, which closes the connection pool for
you:
with WizChatClient(api_key=os.environ["WIZCHAT_API_KEY"]) as wizchat:
chatbots = wizchat.list_chatbots()
Partial-failure semantics (HTTP 422)
apply_config returns an ApplyResult for both full success (HTTP 200) and
partial failure (HTTP 422) — a 422 is not raised. The body is an
ApplyResult (applied / failed / plan), not an error envelope. Inspect
result.failed (None when everything applied) and re-apply after fixing the
offending section — apply is idempotent:
result = wizchat.apply_config(chatbot_id, config)
if result.failed is not None:
print("section failed:", result.failed.op, result.failed.message)
# fix the offending section, then re-apply (idempotent)
Auth/validation failures (400/401/403/404/429) still raise WizChatApiError.
Prune semantics
apply defaults to prune=true — array sections (mcpServers, skills,
domains) are authoritative: resources present on the chatbot but absent
from the document are deleted. Every delete is surfaced in the dry-run plan
first. Pass prune=False for merge-only (create/update, never delete):
wizchat.apply_config(chatbot_id, config, prune=False)
dry_run is sent only as the ?dryRun=true query param; any stray dryRun
on the document body is stripped so the per-call option is the single source of
truth.
Ergonomic helpers
| Method | HTTP | Scope |
|---|---|---|
list_chatbots() |
GET /api/v1/chatbots |
chatbots:read |
get_chatbot(chatbot_id) |
GET /api/v1/chatbots/{id} |
chatbots:read |
get_config(chatbot_id) |
GET /api/v1/chatbots/{id}/config |
chatbots:read (+ per-section read) |
apply_config(chatbot_id, document, *, dry_run=False, prune=None) |
POST /api/v1/chatbots/{id}/apply |
per-section read (dry-run) / write (apply) |
Each helper returns a typed Pydantic model (or list) and raises
WizChatApiError on a non-2xx response (except the documented 422 on apply).
Errors
class WizChatApiError(Exception):
status: int # HTTP status (401, 403, 404, 422, 429, …)
code: str # e.g. "not_found", "insufficient_scope"
message: str # human-readable
details: dict | None # optional structured context
When the body is not the standard { "error": { code, message, details } }
envelope, code falls back to http_<status>.
Generated models
All request/response payloads are typed by Pydantic v2 models in
wizchat_management.models, generated from the OpenAPI components. The key
types are re-exported from the package root:
from wizchat_management import (
ChatbotConfigDocument,
ApplyResult,
Plan,
PublicChatbot,
Spec,
)
Less-common types (e.g. PublicMcpServer, PublicSkill, PublicTelemetry)
live in wizchat_management.models.
Development
The models are generated from the single committed OpenAPI snapshot shared
with the TypeScript SDK (sdks/typescript/openapi.json) — there is no second
copy under sdks/python.
python -m venv .venv
.venv/Scripts/activate # Windows (POSIX: source .venv/bin/activate)
pip install -e ".[dev]"
python scripts/gen.py # regenerate wizchat_management/models.py
pytest # run the httpx-MockTransport suite
scripts/gen.py runs:
datamodel-codegen \
--input ../typescript/openapi.json --input-file-type openapi \
--output wizchat_management/models.py \
--output-model-type pydantic_v2.BaseModel \
--openapi-scopes schemas --use-annotated --field-constraints \
--use-standard-collections --target-python-version 3.10 \
--disable-timestamp --collapse-root-models --formatters black isort
Re-running is deterministic for a fixed input snapshot. The package version
tracks the OpenAPI info.version.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wizchat_management-1.0.0.tar.gz.
File metadata
- Download URL: wizchat_management-1.0.0.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8aed478362b66e1b7ad51aab9606d451664b1626cc7a4868c5c9cc3f998841f1
|
|
| MD5 |
1833cfcaee87c94b50a362cab7685de8
|
|
| BLAKE2b-256 |
f3c16e907d430cef5046aefaf67f7fd785d4a41f0a8694c1d4bcfa8109201de8
|
File details
Details for the file wizchat_management-1.0.0-py3-none-any.whl.
File metadata
- Download URL: wizchat_management-1.0.0-py3-none-any.whl
- Upload date:
- Size: 18.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cd7741f4ba4b821617cf6d33541d9c96a4bf8e7aadb5b03f300411f1f346f70
|
|
| MD5 |
855b7f712c506efdadcea9a8c56d407c
|
|
| BLAKE2b-256 |
f67ab7467bfb35b3bfaf7b20c2984f5a56930d2db9939d6cb048beb0a8f0e253
|