Shared Utilities¶
The shared/ module provides Python utilities imported by all entry
points. Every Python script in BDPD begins with:
bdpd_check_env.py — Environment Guard¶
Enforces that the correct virtual environment (venv_py_bdpd) is active.
Exits immediately with a clear message if not.
Checks the VIRTUAL_ENV environment variable (set automatically by
Python when a venv is activated). Exits with code 1 if:
- No venv is active at all
- A different venv is active
Error messages include the exact command to fix the problem
(source venv_py_bdpd/bin/activate).
This guard prevents accidental execution with system Python or with the wrong virtual environment, which would cause import errors from missing dependencies.
bdpd_logging.py — Logging Factories¶
Two factory functions cover all logging needs:
get_run_logger(run_dir, verbose) → (log, llm_log)¶
For experiment scripts. Writes to <run_dir>/run.log.
| Argument | Type | Description |
|---|---|---|
run_dir |
Path |
Directory created by bdpd_manifest.create_run_dir() |
verbose |
bool |
If True, console shows DEBUG; LLM trace is enabled |
name |
str |
Logger name (default "bdpd") |
Returns a tuple of (log, llm_log) where llm_log is a callable:
In non-verbose mode, llm_log is a no-op. LLM traces are written as
JSON Lines to <run_dir>/llm_trace.jsonl.
get_app_logger(name, log_file, verbose) → (log, _)¶
For persistent processes (agent server, utilities). Writes to a shared log file. The second return value is always a no-op (LLM traces belong in run directories, not app logs).
bdpd_manifest.py — Run Directory Management¶
Creates timestamped run directories with reproducibility metadata.
create_run_dir(base_dir, label, params) → Path¶
Creates a directory base_dir/<timestamp>_<label>/ and writes
manifest.json containing:
| Field | Content |
|---|---|
bdpd_version |
Full git info (commit, tag, branch, dirty flag) |
label |
Experiment label |
started_at |
UTC timestamp |
host |
Machine hostname |
python |
Python version |
platform |
OS platform string |
dependencies |
Versions of openai, flask, numpy, matplotlib, lxml, cairosvg |
params |
User-supplied experiment parameters dict |
write_results(run_dir, data) → Path¶
Writes experiment results to <run_dir>/results.json.
load_manifest(run_dir) → dict¶
Loads and returns the manifest.
load_results(run_dir) → Any¶
Loads and returns results.
bdpd_version.py — Version Information¶
Uses git as the single source of truth. No version numbers are hardcoded anywhere.
get_version() → str¶
Short commit hash (7 chars), e.g. "a3f9c12". Falls back to
"unknown" if git is unavailable.
get_full_version_info() → dict¶
{
"commit": "a3f9c12",
"commit_long": "a3f9c12e4b...",
"tag": "v4.1", # latest semver tag, or ""
"dirty": False, # uncommitted changes present
"branch": "main",
"timestamp": "2026-05-04T14:30:22+00:00"
}
Tag detection uses git describe --tags --abbrev=0 --match v*.
Dirty detection uses git status --porcelain.
version_string() → str¶
Human-readable: "v4.1 (a3f9c12)" or "a3f9c12 [dirty]".
Using the Shared Module¶
All Python scripts should:
# 1. Guard the venv
from bdpd_check_env import require_venv; require_venv()
# 2. Create a run directory (experiment scripts)
from bdpd_manifest import create_run_dir, write_results
run_dir = create_run_dir(Path("experiments/runs"), "my_experiment", params)
# 3. Get a logger
from bdpd_logging import get_run_logger
log, llm_log = get_run_logger(run_dir, verbose=True)
# 4. Log version info
from bdpd_version import version_string
log.info(f"BDPD {version_string()}")