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.
Metadata
Release files for wizchat-management 1.0.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 | |
|---|---|---|---|
| wizchat_management-1.0.0.tar.gz | 22.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wizchat_management-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.1 kB
Release files / wizchat_management-1.0.0.tar.gz
| Download URL | wizchat_management-1.0.0.tar.gz |
|---|---|
| Size | 22.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8aed478362b66e1b7ad51aab9606d451664b1626cc7a4868c5c9cc3f998841f1
|
|
BLAKE2b-256 checksum How to use checksums |
f3c16e907d430cef5046aefaf67f7fd785d4a41f0a8694c1d4bcfa8109201de8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / wizchat_management-1.0.0-py3-none-any.whl
| Download URL | wizchat_management-1.0.0-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4cd7741f4ba4b821617cf6d33541d9c96a4bf8e7aadb5b03f300411f1f346f70
|
|
BLAKE2b-256 checksum How to use checksums |
f67ab7467bfb35b3bfaf7b20c2984f5a56930d2db9939d6cb048beb0a8f0e253
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|