Skip to content

Python SDK

Generate, export and run tests for Amazon Connect contact flows, from Python. It is the testing counterpart to cxblueprint: build or export a flow, then let Diteko derive its grammar, evolve a test suite with Grammatical Evolution, export it, and run it on Connect’s native testing.

This package is a client: it needs a Diteko server. It does nothing on its own. Point it at your team’s Diteko, or start one on this machine with diteko server up (it needs Docker; see https://github.com/Lehlohonolo-Sehako/diteko-selfhost).

The SDK talks to a running Diteko deployment over its REST API. If that deployment requires API keys, set DITEKO_API_KEY (or pass api_key=); otherwise point the SDK only at a deployment inside your network or behind your VPN.

Terminal window
pip install diteko # SDK
pip install "diteko[mcp]" # + MCP server for Claude Desktop / Cursor / VS Code
pip install "diteko[cxblueprint]"
  1. Find your Diteko. Diteko is self-hosted: you need the address of a running deployment. If you run your own (diteko-selfhost), that is http://localhost:8080, which is also the SDK’s default. To start one on this machine (with Docker installed):

    Terminal window
    diteko server up # sets it up in ~/.diteko/server and starts it with Docker

    It needs only Docker (Docker Desktop on macOS and Windows): the self-hosting files travel in this package, and the first start downloads the server image. The first time, it creates a WRITE key and prints the two settings to export (PowerShell syntax on Windows), plus the bootstrap ADMIN key for the console at the same address. diteko server status and diteko server down do what they say; data is kept between runs, and upgrading this package upgrades the server’s files on the next up without touching your settings. --port picks another port, --latest uses the newest diteko-selfhost release instead of the files in this package, and --bundle path a self-hosting folder you already have.

  2. Get a key, if it asks for one. When a deployment requires API keys, whoever runs it creates one for you under Settings › API keys. WRITE is enough for everything here except live runs on Connect. Put it in the environment:

    Terminal window
    export DITEKO_URL=https://diteko.example.internal
    export DITEKO_API_KEY=dk_... # only if the deployment requires keys
  3. Check the connection:

    from diteko import Diteko
    dk = Diteko() # DITEKO_URL and DITEKO_API_KEY from the environment
    print(dk.version()) # {'api': '1.1', 'server': '…', 'auth': 'keys'}
    print(dk.whoami()) # the key in use, or None when keys are off
  4. Run the example. examples/cxblueprint_to_excel.py, also as a notebook, builds a flow with cxblueprint, evolves a suite and writes the Excel test script, in about a minute. Both ship in the source distribution: pip download --no-binary :all: --no-deps diteko, then unpack it.

run = project.evolve(preset="standard").wait(progress=True) # one line on stderr, kept up to date
run = project.evolve(preset="standard").wait(progress=print) # or any callable, given a RunProgress
run.info.best_fitness, run.info.generation, run.info.generations
project.refresh().info # ProjectInfo: grammar, latest run, suite, last execution, typed
execution = suite.publish_to_connect(dry_run=True)
execution.results # [Verdict(test_id, status, message), ...]
execution.passed, execution.failed, execution.inconclusive # inconclusive: Connect could not start it, etc.
from diteko import Diteko
dk = Diteko("http://localhost:8080")
project = dk.projects.from_json("claims.json") # Connect export or cxblueprint output
project.grammar.generate() # derive, store and validate the grammar
run = project.evolve(preset="standard", focus="balanced").wait()
suite = run.suite(top=30, selection="coverage") # or selection="fitness"
for test in suite:
print(test.test_id, test.keys, test.fitness)
suite.export_xlsx("claims-tests.xlsx") # manual test script (ISO/IEC/IEEE 29119-3)
suite.export_native("claims-native.json") # Amazon Connect native test cases
result = suite.publish_to_connect(dry_run=True) # dry run unless you say otherwise
print(result.passed, result.failed, result.verdicts)
from cxblueprint import Flow
from diteko import Diteko
flow = Flow.build("Burger Order")
menu = flow.get_input("Press 1 for Classic or 2 for Veggie", timeout=10)
# ... build the flow as usual ...
project = Diteko().projects.from_cxblueprint(flow) # compiles locally, uploads the JSON
dk.projects.import_from_connect("08e145dc-d959-4094-9021-6f10d8590be2") # from the instance
dk.projects.list() # every project and its next step
dk.projects.get(21601).suite(top=10).export_xlsx()

The two forms are exact reflections of each other. Both are validated by the same parser, and both keep comments.

g = project.grammar.latest()
spec = g.to_json() # {"format": "diteko-grammar/v1", "start": ..., "rules": [...]}
g.replace(spec, format="json").save() # edit as JSON, store as canonical BNF
dk.convert_grammar(bnf_text, "bnf", "json")
preset calls × generations
quick 40 × 15
standard 100 × 50
thorough 200 × 120
focus favours
balanced blocks and branches, plus happy paths and recoveries
coverage visiting as much of the flow as possible
errors timeouts and wrong keys that still end properly
transfers calls that reach an agent queue

Pass population=, generations=, weights={"state_coverage": 1.0} or seed= to go beyond them.

dk = Diteko("https://diteko.internal", api_key="dk_...") # or set DITEKO_API_KEY
dk.whoami() # {"name": "nightly CI", "prefix": "dk_...", "scope": "WRITE", ...}; None if keys are off

A key carries one scope: READ (see and export), WRITE (also create, run and dry-run), PUBLISH_LIVE (also run on Connect for real, which is billed) or ADMIN (also manage keys). Keys are created in the console under Settings, API keys.

Terminal window
DITEKO_URL=http://localhost:8080 DITEKO_API_KEY=dk_... diteko-mcp # the key only if the server requires one
{ "mcpServers": { "diteko": { "command": "diteko-mcp", "env": { "DITEKO_URL": "http://localhost:8080", "DITEKO_API_KEY": "dk_..." } } } }
Tool Does
list_projects every flow under test and its next step
import_flow register a flow from JSON text, a file path, or a Connect flow id
generate_grammar derive, store and validate a flow’s grammar
convert_grammar BNF ⇄ JSON
start_evolution start a run (size, focus, seed)
get_run a run’s progress
export_suite xlsx, json or native to a file
publish_suite start a run on Connect and return at once; dry_run defaults to true, since a live run bills the AWS account
get_execution a Connect run’s status and verdicts; poll it until the status is no longer RUNNING

Each tool carries MCP annotations: read-only tools say so, and publish_suite is marked as reaching an external system. Works with mcp 1.x and 2.x.

Diteko is free to run for your own organisation. If it saves your team time, you can sponsor it on GitHub; the docs list other ways to help.

The package follows Semantic Versioning. See the changelog for what each release changed.

The server reports an API version, MAJOR.MINOR, at GET /api/version. A minor bump only adds endpoints or fields. A major bump changes something an existing client relies on. Each SDK release speaks one API major version, currently 1. On its first call the SDK checks the server’s version:

Server What happens
API 1.x Works.
Another major DitekoError, saying whether to upgrade the SDK or the server
Too old to report a version A warning, then it carries on
Not a Diteko server DitekoError: check DITEKO_URL
Nothing answering DitekoError saying a server is needed and how to point at one; the next call checks again

Diteko(url, check_version=False) skips the check, and dk.version() returns what the server reports.

Terminal window
cd clients/python
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev,mcp]"
pytest # against an in-memory fake of the API
DITEKO_URL=http://localhost:8888 pytest # also runs the live and contract tests against a local stack