Skip to Content
DocsConfiguration

Configuration

Everything you can tune.

Environment variables

The SDK reads these at beval.init() unless overridden by arguments.

VariableDefaultPurpose
BEVAL_API_KEYYour project API key. If unset, the SDK is a no-op.
BEVAL_API_URLhttps://ai-gateway.bolder.servicesGateway base URL. Override for self-hosted.
BEVAL_PROJECT_IDDefault project ID for all logs.
BEVAL_DEFAULT_MODEL_IDFallback model_id when none is passed per-call.
BEVAL_DEBUGfalseVerbose SDK logging. 1 / true / yes to enable.

beval.init() arguments

Pass these to override environment variables:

beval.init( api_key="bv_...", api_url="https://ai-gateway.example.com", project_id="...", default_model_id="gpt-4o-mini", debug=True, redact=my_redact_fn, # advanced timeout_s=5.0, max_queue_size=10_000, batch_size=20, flush_interval_s=1.0, max_retries=3, extra={"service": "payments-api", "env": "prod"}, )

See the API Reference → Config for all fields.

extra on init

Merged into every log’s extra field. Useful for service-wide metadata that the dashboard can filter on:

beval.init(extra={"service": "api", "env": "prod", "version": "2024.11"}) beval.log(input="...", output="...") # → extra = {"service": "api", "env": "prod", "version": "2024.11"} beval.log(input="...", output="...", extra={"user_id": "u_42"}) # → extra = {"service": "api", "env": "prod", "version": "2024.11", "user_id": "u_42"}

Per-call extra is shallow-merged over the init defaults.

Redaction

Strip PII before it leaves the process. Pass a function that takes a payload dict and returns a payload dict:

import re def redact(payload: dict) -> dict: for key in ("input", "output"): if payload.get(key): payload[key] = re.sub(r"\b[\w.+-]+@[\w.-]+\b", "[EMAIL]", payload[key]) payload[key] = re.sub(r"\b\d{3}-\d{2}-\d{4}\b", "[SSN]", payload[key]) return payload beval.init(redact=redact)

The hook runs on the background thread, just before the HTTP POST. Exceptions in the hook are caught and logged — they do not drop the log, but redaction may not have applied. Test your redact function independently.

Custom extras

The SDK runs your redact after init.extra is merged, so redaction applies to the init defaults too. If you want to pass sensitive service metadata that should not be redacted, keep it in extra and key off known-safe fields in your redactor:

REDACT_KEYS = {"input", "output", "thinking_trace", "error_message"} def redact(payload: dict) -> dict: for key, value in payload.items(): if key in REDACT_KEYS and isinstance(value, str): payload[key] = scrub_pii(value) return payload

Queue tuning

beval.init( max_queue_size=50_000, # raise if you have high-throughput services batch_size=50, # currently unused (batch ingest coming) flush_interval_s=0.5, # how often the worker wakes to send max_retries=5, # 408/429/5xx retries per log timeout_s=10.0, # per-request HTTP timeout )

When to raise max_queue_size — if your service can produce >10k logs between flushes (e.g. during a 30-second gateway outage at 500 rps, you’d overflow). Bigger queue = more RAM when the gateway is slow.

When to raise max_retries — usually don’t. The SDK already drops-and-warns after retries, and at-least-once delivery over a flaky network is fine for observability.

Disabling the SDK

Don’t call beval.init(), or unset BEVAL_API_KEY. The module-level beval.log() becomes a no-op returning False. Existing code keeps running.

For tests:

# conftest.py import os os.environ.pop("BEVAL_API_KEY", None)

Logging the SDK itself

The SDK uses the standard logging module under the name beval. Enable verbose output:

import logging logging.getLogger("beval").setLevel(logging.DEBUG)

Or via env var:

export BEVAL_DEBUG=1

Debug logs include per-send events (sent log <uuid>), queue overflow warnings, and retry attempts.

Last updated on