Method signatures, parameter schemas, return types, runnable code examples, and framework integrations for the Blocklog Python client.
Initialize the global SDK configuration. Call once at application startup.
def init(
api_key: str | None = None,
*,
base_url: str | None = None,
signing_key: str | None = None,
timeout: float | None = None,
max_retries: int | None = None,
debug: bool = False,
) -> BlocklogClientapi_key · str, optionalKey for verification. Falls back to BLOCKLOG_API_KEY.
base_url · str, optionalCustom API endpoint override. Falls back to BLOCKLOG_BASE_URL.
signing_key · str, optionalHMAC-SHA256 key for tamper-evident log signatures. Falls back to BLOCKLOG_SDK_SIGNING_KEY.
timeout · float, optionalRequest timeout in seconds. Default is 10.
max_retries · int, optionalIngestion retries. Default is 3.
import blocklog
blocklog.init(api_key="blk_live_xxxx", debug=True)Trace an AI agent function, linking it to a Blocklog session. Handles sync and async functions automatically.
def agent(
func: F | None = None,
*,
name: str | None = None,
version: str = "1.0",
tags: list[str] | None = None,
metadata: dict[str, Any] | None = None,
) -> F | Callable[[F], F]name · str, optionalHuman-readable agent name. Defaults to func.__name__.
version · strSemver-style version string. Default is "1.0".
tags · list[str], optionalOptional list of string tags.
metadata · dict, optionalArbitrary extra data attached to the agent session.
@blocklog.agent(name="stock-trader", version="2.0", tags=["prod"])
def run_trading(ticker):
passWrap a helper function or external API call to record it as a TOOL_CALL event. Inherits trace context from the surrounding @agent.
def tool(
func: F | None = None,
*,
name: str | None = None,
schema: dict[str, Any] | None = None,
tags: list[str] | None = None,
metadata: dict[str, Any] | None = None,
) -> F | Callable[[F], F]name · str, optionalHuman-readable tool name. Defaults to func.__name__.
schema · dict, optionalOptional dict describing the input schema.
tags · list[str], optionalOptional string tags.
metadata · dict, optionalArbitrary extra data.
@blocklog.tool(name="fetch-price", tags=["market-data"])
def get_price(ticker):
return 189.30Define a block for recording structured inputs, outputs, and review tasks associated with an AI decision.
def decision(
*,
type: str,
asset: str | None = None,
confidence: float | None = None,
metadata: dict[str, Any] | None = None,
agent_id: str | None = None,
trace_id: str | None = None,
) -> Generator[DecisionContext, None, None]type · strDecision type identifier (e.g. "CREDIT_APPROVAL").
asset · str, optionalAsset or entity this decision evaluates.
confidence · float, optionalModel confidence score from 0.0 to 1.0.
metadata · dict, optionalExtra structured audit fields.
agent_id · str, optionalLinks this decision to a specific agent session.
trace_id · str, optionalLinks this decision to a specific trace.
DecisionContextrecord_input(**kwargs)Record structured inputs. Returns self.
record_output(**kwargs)Record structured outputs. Returns self.
tag(*tags)Attach string labels. Returns self.
request_approval(reason, reviewer=None)Non-blocking request for human approval. Returns self.
verify()Verify the decision after the with block exits.
with blocklog.decision(type="BUY", asset="AAPL", confidence=0.9) as d:
d.record_input(price=189.30)
d.tag("high-conviction")
d.record_output(order_id="ord_99")Request human review for an action. Triggers webhooks and Slack notifications asynchronously.
def request(
decision_id: str | None = None,
*,
reason: str,
reviewer: str | None = None,
log_id: str | None = None,
metadata: dict[str, Any] | None = None,
) -> dict[str, Any]decision_id · str, optionalID of the decision this approval request relates to.
reason · strWhy human review is required.
reviewer · str, optionalEmail or identifier of the assigned reviewer.
log_id · str, optionalID of a specific log entry if not tied to a decision.
metadata · dict, optionalArbitrary extra audit data.
blocklog.approval.request(
decision_id="dec_123",
reason="Price exceeds risk limits",
reviewer="cro@company.com"
)Instantiate a session to examine execution traces, staleness heatmaps, and counterfactual outcomes.
def replay(
trace_id: str,
*,
token_id: str | None = None,
metadata: dict[str, Any] | None = None,
) -> ReplaySessiontrace_id · strTrace ID to reconstruct.
token_id · str, optionalRestrict the replay to a specific token within the trace.
metadata · dict, optionalExtra context attached to the replay session.
session = blocklog.replay("trace-uuid")
cause = session.root_cause()
print(cause["description"])Confirm a single log entry has not been tampered with since creation.
def log(log_id: str) -> dict[str, Any]log_id · strID of the log entry to verify.
result = blocklog.verify.log("log-uuid")
assert result["status"] == "verified"Built-in instrumentation for LangChain, LangGraph, the OpenAI SDK, and LiteLLM. Each integration wires into native hooks and emits structured audit events to the Blocklog ingest API.
Attach a callback handler to any chain, agent, or LLM to capture chain, model, and tool lifecycle events.
import blocklog
client = blocklog.init(api_key="blk_...")
handler = client.instrument_langchain()chain.invoke(inputs, config={"callbacks": [handler]})| Event | Causality type | Fired when |
|---|---|---|
agent.chain.started | chain_start | A chain begins; includes inputs and input_keys. |
agent.chain.completed | chain_end | A chain finishes successfully; includes outputs. |
agent.chain.errored | chain_error | A chain raises an exception. |
agent.model.started | llm_start | An LLM call begins; includes serialized model info and prompts. |
agent.model.completed | llm_end | An LLM call finishes; includes the full response. |
agent.model.errored | llm_error | An LLM call raises an exception. |
agent.tool.started | tool_start | A tool begins execution; includes the raw input string. |
agent.tool.completed | tool_end | A tool finishes; includes output. |
agent.tool.errored | tool_error | A tool raises an exception. |
Extends the LangChain handler pattern with graph-native event families. Inspects the serialized payload to emit graph, node, and subgraph events accurately.
import blocklog
client = blocklog.init(api_key="blk_...")
handler = client.instrument_langgraph()result = graph.invoke(state, config={"callbacks": [handler]})
# Or via RunnableConfig
from langchain_core.runnables import RunnableConfig
result = graph.invoke(state, config=RunnableConfig(callbacks=[handler]))Graph lifecycle
| Event | Causality type | Fired when |
|---|---|---|
agent.graph.started | graph_start | The top-level CompiledGraph begins; includes graph_name, inputs, and input_keys. |
agent.graph.completed | graph_end | The graph finishes successfully; includes outputs. |
agent.graph.errored | graph_error | The graph raises an unhandled exception. |
Node lifecycle
| Event | Causality type | Fired when |
|---|---|---|
agent.graph.node.started | node_start | A node begins; includes node_name and inputs. |
agent.graph.node.completed | node_end | A node finishes; includes node_name and outputs. |
agent.graph.node.errored | node_error | A node raises an exception; includes node_name and error details. |
Subgraph lifecycle
| Event | Causality type | Fired when |
|---|---|---|
agent.graph.subgraph.started | subgraph_start | A nested subgraph begins; includes subgraph_name and inputs. |
agent.graph.subgraph.completed | subgraph_end | A nested subgraph finishes; includes outputs. |
Checkpoint lifecycle
| Event | Causality type | Fired when |
|---|---|---|
agent.graph.checkpoint.started | checkpoint_start | LangGraph is about to write a checkpoint; includes thread_id and checkpoint_ns. |
agent.graph.checkpoint.completed | checkpoint_end | A checkpoint is persisted; includes checkpoint_id, thread_id, and checkpoint_ns. |
Instruments create methods on OpenAI resource classes directly. Every OpenAI(), AsyncOpenAI(), and AzureOpenAI() instance is instrumented automatically.
import blocklog
client = blocklog.init(api_key="blk_...")
client.instrument_openai_agents()import openai
from blocklog.integrations.openai_agents import instrument_openai
blocklog_client = blocklog.init(api_key="blk_...")
openai_client = openai.OpenAI(api_key="...")
instrument_openai(blocklog_client, openai_client=openai_client)| Event | Causality type | Fired when |
|---|---|---|
agent.model.started | llm_start | A chat.completions.create or responses.create call begins; includes model, messages, and request parameters. |
agent.model.completed | llm_end | The call finishes; includes the full response, token usage, duration_s, and streamed flag. |
agent.model.errored | llm_error | The call raises an exception. |
Registers via litellm.callbacks using LiteLLM's CustomLogger base class with no monkey-patching required.
import blocklog
client = blocklog.init(api_key="blk_...")
handler = client.instrument_litellm()import litellm
# Replace or append to existing callbacks
litellm.callbacks = [handler]| Event | Causality type | Fired when |
|---|---|---|
agent.model.pre_call | llm_pre_call | Before the HTTP request is dispatched; includes model, messages, stream, and call ID. |
agent.model.post_call | llm_post_call | After the API responds, before the success/failure split. |
agent.model.stream_chunk | llm_stream_chunk | For each individual chunk on the sync streaming path. |
agent.model.completed | llm_end | A call finishes successfully (sync or async); includes response, usage, and cost. |
agent.model.errored | llm_error | A call fails (sync or async); includes error_type and duration_s. |