zooqueenandHanzo Dev 7ef22afa72 fix(iam): call the native routes, not the verbs the server is deleting
23 call sites across hanzo-iam and hanzo-tools-iam reached IAM over the legacy
verb surface — get-user, get-users, get-application(s), get-organization(s),
get-providers, get-role(s), get-user-count, get-user-roles, and the
oauth/access_token spelling. Those routes are being removed: HIP-0111 forbids
them, and a capability with an RFC uses its RFC.

Two things had to change together, which is why this adds routes.py rather than
editing the literals in place. The verb surface answered {status, msg, data} at
HTTP 200 even for a miss; the native surface returns the object at the top level,
uses real status codes, and NAMES its lists — {"users": [...]}, not
{"data": [...]}.

Swapping only the path is the dangerous half-migration, and hanzo-tools-iam shows
why: it did `users = data if isinstance(data, list) else []`, so against a native
response it would have reported ZERO users for a healthy org. Not an error — an
empty list. Both halves changed there.

routes.unwrap reads either shape so a fleet mid-rollout keeps working, and still
RAISES on the legacy error envelope because callers depended on that rather than
on a falsy return. It is deliberately temporary: once every server serves native
only, the envelope branch is dead and goes with it. Only a body whose keys are
exactly the envelope's is unwrapped, so a native row with its own `data` column
survives.

These admin methods had no coverage while they called the verb surface — the
reason migrating them blind was the risk. tests/test_routes.py pins it: no route
may contain "/get-", the token endpoint must be the one discovery advertises,
every list route must declare its key (a missing one unwraps to [] and reads as
empty), and neither client may carry a path literal. Falsified — restore a verb
in the table or in a client and the suite names it.

99 pass. tests/test_fastapi.py cannot collect in this environment
(starlette/httpx version clash, unrelated to this change); hanzo-tools-iam's
suite cannot either (`from mcp.server import FastMCP` against the installed MCP
SDK) — both verified pre-existing by reproducing them with these changes stashed.

Rebased onto upstream's IAM_ROUTE_PREFIX refactor rather than merged: that
refactor centralised the prefix but kept the verbs, so the two changes compose.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 15:41:22 -07:00
2025-03-15 03:31:14 +00:00
2025-03-15 03:31:14 +00:00
2026-06-26 11:57:39 -07:00
2025-03-15 03:56:11 +00:00

Hanzo Python SDK

Hanzo Python SDK

The flagship Python SDK for the Open AI Cloud — models, agents, tools, memory, and MCP in one install.

CI PyPI Python Version License

This is the most complete Hanzo SDK — a uv workspace of 60+ composable packages covering the full AI surface: the typed cloud client, an agent framework, the Model Context Protocol server and tools, persistent memory + RAG, distributed compute, and a batteries-included CLI. If you build AI in Python, start here.

Install

pip install hanzo          # flagship: CLI + agents + MCP + client

Or install exactly what you need:

pip install hanzoai        # just the typed cloud API client
pip install "hanzo[all]"   # everything, including optional extras

Quickstart

from hanzoai import ApiClient, Configuration, AiOpenAICompatibleApi
from hanzoai import AiChatCompletionRequest, AiChatMessage

config = Configuration(host="https://api.hanzo.ai", access_token="sk-...")

with ApiClient(config) as client:
    ai = AiOpenAICompatibleApi(client)
    resp = ai.ai_create_chat_completion(
        AiChatCompletionRequest(
            model="zen-coder",
            messages=[AiChatMessage(role="user", content="Ship it.")],
        )
    )
    print(resp.choices[0].message.content)

Every route is https://api.hanzo.ai/v1/<service>/*. Models come from the Zen family (our own models) plus any provider you connect — one typed client, no proxy in the middle.

Packages

The workspace splits cleanly by concern. The headline packages:

Package Purpose
hanzoai Typed cloud API client (generated from the Hanzo OpenAPI surface).
hanzo The hanzo CLI + runtime that ties everything together.
hanzo-mcp Model Context Protocol server — discovers tools via entry points.
hanzo-agents / hanzo-agent Agent framework — build and orchestrate agents and swarms.
hanzo-network Distributed AI compute and node orchestration.
hanzo-memory Persistent memory + RAG (SQLite, optional vector backends).
hanzo-tools-* 60+ single-concern tool packages (shell, browser, fs, code, vector, iam, …), each exposing a TOOLS list.
python-sdk/
└── pkg/
    ├── hanzoai/          # typed cloud client (OpenAPI-generated)
    ├── hanzo/            # CLI + runtime meta package
    ├── hanzo-mcp/        # MCP server (entry-point tool discovery)
    ├── hanzo-agents/     # agent framework
    ├── hanzo-network/    # distributed compute
    ├── hanzo-memory/     # memory + RAG
    └── hanzo-tools-*/    # composable tool packages

CLI

pip install hanzo gives you the hanzo command:

hanzo chat            # chat with the Zen models
hanzo node            # start / manage a local compute node
hanzo mcp             # run the MCP server for your editor or agent
hanzo agent           # build and run agents
hanzo run             # run a workflow
hanzo cloud           # manage cloud resources
hanzo search          # AI-powered search

Run hanzo --help for the full command tree.

Model Context Protocol (hanzo-mcp)

hanzo-mcp hosts the MCP server and discovers tools through [project.entry-points."hanzo.tools"], so any installed hanzo-tools-* package lights up automatically.

from hanzo_mcp import create_mcp_server

server = create_mcp_server()
server.register_tool(my_tool)
server.start()

Agents (hanzo-agents)

from hanzo_agents import Agent, Swarm

agent = Agent(
    name="researcher",
    model="zen-coder",
    instructions="You are a research assistant.",
)

swarm = Swarm([agent])
result = await swarm.run("Research quantum computing.")

Network (hanzo-network)

from hanzo_network import LocalComputeNode, DistributedNetwork

node = LocalComputeNode(node_id="node-001")
network = DistributedNetwork()
network.register_node(node)

Memory (hanzo-memory)

Persistent memory and RAG backed by SQLite, with optional vector search (sqlite-vec, lancedb, kuzu). Global state lives in ~/.hanzo/; per-project state in .hanzo/.

from hanzo_memory import MemoryService

memory = MemoryService()
await memory.store("key", "value")
result = await memory.retrieve("key")

Development

This is a uv workspace.

git clone https://github.com/hanzoai/python-sdk.git
cd python-sdk
uv sync --all-packages       # install the whole workspace

uv run pytest tests/ -v      # run tests
make lint                    # ruff lint
make format                  # ruff format
make type-check              # mypy / pyright

Per-package work:

uv run pytest pkg/hanzo-mcp -v
cd pkg/hanzo && uv build

Configuration

HANZO_API_KEY=your-api-key
HANZO_BASE_URL=https://api.hanzo.ai
HANZO_LOG_LEVEL=INFO

Or ~/.hanzo/config.yaml:

api:
  key: your-api-key
  base_url: https://api.hanzo.ai
logging:
  level: INFO

Security

  • Transport is TLS 1.3+. Secrets belong in a KMS, never in source or plaintext.
  • SOC 2 audit in progress; HIPAA BAA available.

Report vulnerabilities to [email protected]. See SECURITY.md.

Contributing

Contributions welcome — see CONTRIBUTING.md. Use type hints, add tests for new behavior, and run make lint before opening a PR.

License

Apache License 2.0 — see LICENSE.

Support

Hanzo — the Open AI Cloud

Open source · every language · on-chain settlement. hanzo.ai · docs.hanzo.ai

SDKs in every language — Python (flagship) · TypeScript · Go · Rust · C++ · Swift · Kotlin · umbrella

S
Description
No description provided
Readme Apache-2.0
76 MiB
Languages
Python 99.9%