mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
Cloud's APIKeyPrefixes admits pk- and sk- only (auth_identity.go, 4b030b77). The lsp tool still told the user to set an hk- key, which cloud resolves to no principal — following the message produced a key that could never authenticate. The message is now a single NO_KEY beside the resolver that mints it, exported from hanzo_tools.core, so a second tool reporting it cannot spell it differently. Resolution order is untouched: HANZO_API_KEY, then ~/.hanzo/config.json .apiKey, then the CLI's IAM session. vector_index names the split cloud actually draws: pk- publishable for read, sk- secret for write. Co-authored-by: Hanzo Dev <[email protected]>
2.4 KiB
2.4 KiB
hanzo-flags
Feature flags + A/B testing for Python, on the Hanzo native flags engine.
The Python client for cloud /v1/flags — the same PostHog-compatible evaluation
endpoint the Rust core, Go binding, and @hanzo/flags (TypeScript) all speak. One
flag definition, evaluated identically in every language.
Zero runtime dependencies — stdlib urllib only. A flag check must never drag
a dependency tree into a service.
Install
pip install hanzo-flags # or: uv add hanzo-flags
Use
from hanzo_flags import HanzoFlags
flags = HanzoFlags("https://api.hanzo.ai", token="sk-...")
flags.load("user-123", person_properties={"plan": "pro"})
if flags.is_enabled("checkout-exp"):
...
variant = flags.variant("pricing-test") # "control" | "b" | None
payload = flags.payload("pricing-test") # the flag's JSON payload, or None
Group targeting (orgs/teams):
from hanzo_flags import Group
flags.load(
"user-123",
groups={"0": Group(key="acme", properties={"tier": "gold"})},
)
Async (asyncio services):
from hanzo_flags import AsyncHanzoFlags
flags = AsyncHanzoFlags("https://api.hanzo.ai", token="sk-...")
await flags.load("user-123")
if flags.is_enabled("checkout-exp"):
...
One-shot:
from hanzo_flags import evaluate
res = evaluate("https://api.hanzo.ai", "user-123", token="sk-...")
res.is_enabled("checkout-exp")
Guarantees
- Fail-open. A transport or decode error returns the last good (or empty)
result with
errors_while_computingset —load()never raises on the hot path. - Cached by context + TTL (default 15s). Re-evaluating the same context inside
the TTL is free, so a hot path may call
load()freely.
The family
| Language | Package | Mode |
|---|---|---|
| Rust | hanzo-flags crate |
native (the evaluation core) |
| Go | cloud/clients/flags |
in-process via FFI to the Rust core |
| TypeScript | @hanzo/flags |
HTTP to /v1/flags (browser + node) |
| Python | hanzo-flags |
HTTP to /v1/flags (this package) |
All four resolve the same flag to the same value: the definitions live once in the
cloud flags cockpit (/v1/flags/defs), and every client evaluates against them.