Skip to content

briefcase

Terminal window
pip install briefcase-ai

Top-level exports.

capture()

from briefcase import capture
@capture(decision_type="classification")
def classify_ticket(text: str) -> str:
return "account_access"
classify_ticket("reset my password")
capture(
fn=None,
*,
decision_type=None,
context_version=None,
max_input_chars=1000,
max_output_chars=1000,
exporter=None,
async_capture=True,
capture_content="full",
redact=None,
)

The @capture decorator records a lightweight dict for each call and forwards it to an exporter. It does not itself persist a native DecisionSnapshot; for storage and replay use the native runtime objects below. capture_content is full, hash, or none; the redact hook applies only to full-mode text. With no configured exporter, the wrapper calls through without building a record.

setup()

from briefcase import setup
config = setup(
exporter=None,
storage=None,
guardrail_packs=None,
)
setup(
exporter=None,
router=None,
webhook_url=None,
webhook_secret=None,
events=None,
event_bus=None,
storage=None,
guardrail_packs=None,
) -> BriefcaseConfig

init(), init_with_config(), is_initialized()

import briefcase
briefcase.init() # start the native runtime
print(briefcase.is_initialized())

init() must be called once before using the native storage and replay layer. Use init_with_config(worker_threads=2) instead of init() to size the worker pool. The runtime can only be initialized once per process.

observe()

import briefcase
mem = briefcase.observe("memory")
@briefcase.capture(async_capture=False)
def classify_ticket(text: str) -> str:
return "account_access"
classify_ticket("reset my password")
print(mem.records[0]["function_name"]) # "classify_ticket"
observe(exporter="console", *, level=None) -> BaseExporter

Wires up decision export in one call. Without it, @capture records decisions but has nowhere to send them. exporter accepts a BaseExporter instance or a shorthand string: "console" (default, ConsoleExporter), "memory" (MemoryExporter), or a path ending in .jsonl (JSONLFileExporter). Returns the configured exporter, so a MemoryExporter can be inspected via .records. Pass level= to also enable logging at that level. @capture exports in a background thread by default, so use @capture(async_capture=False) when you want a record to appear synchronously (for example to read MemoryExporter.records right after the call).

enable_logging(), set_log_level(), disable_logging(), get_logger()

import briefcase
logger = briefcase.enable_logging("DEBUG") # opt-in; silent by default
briefcase.set_log_level("INFO")
module_logger = briefcase.get_logger("briefcase.app")
briefcase.disable_logging()
enable_logging(level="INFO", *, stream=None, fmt=None, datefmt=None) -> logging.Logger
set_log_level(level) -> None
disable_logging() -> None
get_logger(name) -> logging.Logger

The library attaches only a NullHandler and emits nothing until you opt in. enable_logging idempotently adds a single StreamHandler (default sys.stderr) and returns the briefcase logger. Setting the environment variable BRIEFCASE_LOG_LEVEL=DEBUG enables logging automatically at import.

BriefcaseConfig

from briefcase import BriefcaseConfig
config = BriefcaseConfig.get()
registry = config.guardrail_registry
config.reset()

DecisionSnapshot

from briefcase import DecisionSnapshot, Input, Output, ModelParameters
decision = DecisionSnapshot("classify_ticket")
decision.add_input(Input("text", "reset my password", "string"))
output = Output("category", "account_access", "string")
output.with_confidence(0.92)
decision.add_output(output)
decision.with_execution_time(12.0)
decision.with_module("triage_service")
decision.add_tag("environment", "production")
print(decision.function_name, decision.fingerprint()[:12], decision.content_hash()[:12])
DecisionSnapshot(function_name)
.add_input(input)
.add_output(output)
.add_tag(key, value)
.with_model_parameters(params)
.with_execution_time(ms)
.with_module(module)
.with_agent(agent)
.with_hardware(hardware)
.with_error(error, error_type)
.with_scorecard(scorecard)
.fingerprint() # hash of function name, inputs, and model name
.content_hash() # hash of everything decided, outputs included
# attributes: function_name, module_name, inputs, outputs, tags, execution_time_ms

fingerprint() identifies the question: it hashes the function name, the input names and values, and the model name, so the same inputs share a fingerprint whatever they answered. content_hash() covers what was decided, adding outputs, model parameter values, module, tags, and any error, while excluding ids and timestamps so a holder of the record can recompute it. Both are SHA-256 and unkeyed.

Snapshot

from briefcase import Snapshot
session = Snapshot("session")
session.add_decision(decision)
print(len(session.decisions))

SnapshotQuery

from briefcase import SnapshotQuery
query = SnapshotQuery()
query.with_function_name("classify_ticket")
query.with_tag("environment", "production")
query.with_limit(50)
query.with_offset(0)

Input, Output

from briefcase import Input, Output
text_input = Input("text", "reset my password", "string")
print(text_input.name, text_input.value, text_input.data_type)
result = Output("category", "account_access", "string")
result.with_confidence(0.92)
print(result.confidence)

ModelParameters

from briefcase import ModelParameters
params = ModelParameters("claude-3-haiku")
params.with_provider("anthropic")
params.with_parameter("temperature", 0.0)
params.with_parameter("max_tokens", 256)

ExecutionContext

from briefcase import ExecutionContext
context = ExecutionContext()
context.with_runtime_version("3.11")
context.with_dependency("transformers", "4.40.0")
context.with_env_var("REGION", "us-east-1")
context.with_random_seed(42)

HardwareMetadata

from briefcase import HardwareMetadata
hardware = HardwareMetadata("gpu", "A10G")
hardware.with_provider("aws")
hardware.with_vram(24.0)