Skip to main content

Python client for the ai-heeczer ingestion service.

Project description

cognizhi-heeczer (Python)

Async Python client for the ai-heeczer ingestion service.

⚠️ Pre-1.0 surface. The HTTP envelope contract (envelope_version 1) is stable; the typed wrapper API may evolve until we ship 1.0.0.

Install

Pre-release. cognizhi-heeczer is not on PyPI yet (see plan 0012). Until then, install from source: uv sync --project bindings/heeczer-py.

uv add cognizhi-heeczer

Requires Python ≥ 3.11.

Usage

import asyncio
from heeczer import HeeczerClient

async def main() -> None:
    async with HeeczerClient(
        base_url="https://ingest.example.com",
        api_key="…",
    ) as client:
        result = await client.ingest_event(
            workspace_id="ws_default",
            event=canonical_event,  # see core/schema/event.v1.json
        )
        print(result["score"]["final_estimated_minutes"])

asyncio.run(main())

Error handling

Every client method raises :class:heeczer.HeeczerApiError on a non-2xx response. The error carries the closed kind enum from the ingestion service's envelope:

from heeczer import HeeczerApiError

try:
    await client.ingest_event(workspace_id="ws", event=bad_event)
except HeeczerApiError as err:
    if err.kind == "schema":
        ...

Configuration

Argument Type Default Description
base_url str required Base URL of the ingestion service. Trailing slash is stripped.
api_key str | None None Sent as x-heeczer-api-key.
timeout float 10.0 Per-request timeout in seconds.
transport httpx.AsyncBaseTransport | None None Inject a custom transport (e.g. httpx.MockTransport in tests).

Methods

Method HTTP Returns
healthz() GET /healthz bool
version() GET /v1/version VersionResponse
ingest_event(workspace_id, event) POST /v1/events IngestEventResponse
test_score_pipeline(event, profile=…, tier_set=…, tier_override=…) POST /v1/test/score-pipeline TestPipelineResponse (gated by the test-orchestration feature flag)

Error kinds

HeeczerApiError.kind is a closed Literal mirroring the ingestion service envelope:

Kind When
schema Event failed canonical schema validation.
bad_request Malformed JSON or missing top-level fields.
scoring Engine rejected a normalized event (e.g. unknown tier id).
storage Persistence layer error.
not_found Read endpoint did not find the resource.
forbidden Auth or RBAC denied the request.
feature_disabled Endpoint exists but the feature flag is off.
unknown Non-JSON 5xx body; the raw text is in api_message.

Runnable example

See examples/python/quickstart.py and the cross-language index in examples/README.md.

Common patterns

Validate locally before sending (avoids a network round-trip on bad events). The schema is JSON Schema Draft 2020-12; use jsonschema or fastjsonschema:

import json, jsonschema

with open("core/schema/event.v1.json") as f:
    schema = json.load(f)

jsonschema.validate(event, schema)  # raises jsonschema.ValidationError if invalid

Surface schema field errors from the service:

try:
    await client.ingest_event(workspace_id="ws", event=event)
except HeeczerApiError as err:
    if err.kind == "schema":
        # err.api_message contains the field-level detail from the server envelope.
        print("schema rejection:", err.api_message)

Batching note. POST /v1/events:batch (single-transaction, partial-success semantics) is planned but not yet shipped — see plan 0004. Until then, use asyncio.gather for concurrent sends.

Contract

The SDK speaks envelope_version: "1" to the ingestion service per ADR-0011. Additive fields land without breaking the typed surface (ScoreResult is a TypedDict with total=False).

Synchronous client

For scripts and notebooks where no event loop is running, use the SyncHeeczerClient wrapper:

from heeczer import SyncHeeczerClient

with SyncHeeczerClient(base_url="https://ingest.example.com", api_key="…") as client:
    result = client.ingest_event(workspace_id="ws_default", event=my_event)
    print(result["score"]["final_estimated_minutes"])

SyncHeeczerClient exposes the same methods as HeeczerClient (healthz, version, ingest_event, test_score_pipeline), all blocking. Internally it calls asyncio.get_event_loop().run_until_complete(). Do not mix it with an already-running asyncio loop (e.g. inside async def); use HeeczerClient directly there instead.

Framework adapters

LangGraph

Wrap SyncHeeczerClient inside a custom LangGraph node to record each agent step's cost before passing control downstream:

from langgraph.graph import StateGraph
from heeczer import SyncHeeczerClient
from typing import TypedDict

class AgentState(TypedDict):
    event: dict
    score: dict | None

def heeczer_node(state: AgentState) -> AgentState:
    with SyncHeeczerClient(base_url="http://localhost:3000") as client:
        resp = client.ingest_event(
            workspace_id="ws_default",
            event=state["event"],
        )
    return {**state, "score": resp["score"]}

builder = StateGraph(AgentState)
builder.add_node("heeczer", heeczer_node)

In async LangGraph graphs call the async client instead:

async def heeczer_node(state: AgentState) -> AgentState:
    async with HeeczerClient(base_url="http://localhost:3000") as client:
        resp = await client.ingest_event(
            workspace_id="ws_default",
            event=state["event"],
        )
    return {**state, "score": resp["score"]}

Google ADK

Google's Agent Development Kit (ADK) uses an async event-loop internally. Use HeeczerClient directly in ADK tool callbacks:

from google.adk.tools import FunctionTool
from heeczer import HeeczerClient

async def record_step(workspace_id: str, event: dict) -> dict:
    """Record an agent step with heeczer and return the score."""
    async with HeeczerClient(base_url="http://localhost:3000") as client:
        return await client.ingest_event(workspace_id=workspace_id, event=event)

heeczer_tool = FunctionTool(record_step)

Attach heeczer_tool to your ADK Agent via tools=[heeczer_tool]. The return value of record_step is serialised by ADK and forwarded as the tool response to the model.

Development

uv sync --extra dev
uv run pytest
uv run ruff check
uv run mypy

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cognizhi_heeczer-0.5.1.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cognizhi_heeczer-0.5.1-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file cognizhi_heeczer-0.5.1.tar.gz.

File metadata

  • Download URL: cognizhi_heeczer-0.5.1.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cognizhi_heeczer-0.5.1.tar.gz
Algorithm Hash digest
SHA256 7958a297afdc029ad6118669f91667c88671c435c16479784a05c48f01b09c03
MD5 491057f0776c5ac4f24db9bfa41f43b1
BLAKE2b-256 76e15d8ea58bf4df3c1cd291aba1450fa6b65ba0d4ede7da8358d1c44b9a4b25

See more details on using hashes here.

Provenance

The following attestation bundles were made for cognizhi_heeczer-0.5.1.tar.gz:

Publisher: release.yml on cognizhi/ai-heeczer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cognizhi_heeczer-0.5.1-py3-none-any.whl.

File metadata

File hashes

Hashes for cognizhi_heeczer-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9bf6757093f21278bdb814881fd6cabd038cfca6a557c07693660874e89983c9
MD5 4d9f8859db0a888db76e3345c867b78b
BLAKE2b-256 26640c86f3302dc702c2f6cb900716e2722d7245fc78ca4deb09c4678760a420

See more details on using hashes here.

Provenance

The following attestation bundles were made for cognizhi_heeczer-0.5.1-py3-none-any.whl:

Publisher: release.yml on cognizhi/ai-heeczer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page