Source code for design_research_experiments.adapters.analysis

"""Downstream-analysis export adapter."""

from __future__ import annotations

import importlib
from collections.abc import Sequence
from pathlib import Path
from typing import Any

from ..artifacts import export_canonical_artifacts
from ..conditions import Condition
from ..schemas import ValidationError
from ..study import RunResult, Study

EVENT_REQUIRED_COLUMNS = (
    "timestamp",
    "record_id",
    "text",
    "session_id",
    "actor_id",
    "event_type",
    "meta_json",
)


[docs] def export_analysis_tables( study: Study, *, conditions: Sequence[Condition], run_results: Sequence[RunResult], output_dir: str | Path | None = None, include_sqlite: bool = False, validate_with_analysis_package: bool = False, ) -> dict[str, Path]: """Export canonical analysis tables aligned with downstream workflows.""" paths = export_canonical_artifacts( study=study, conditions=conditions, run_results=run_results, output_dir=output_dir, include_sqlite=include_sqlite, ) if validate_with_analysis_package: _run_optional_analysis_validation(paths["events.csv"]) return paths
def _run_optional_analysis_validation(events_csv_path: Path) -> None: """Optionally run validation hooks from design-research-analysis when available.""" module = _load_analysis_validation_module() if module is None: return validator = getattr(module, "validate_experiment_events", None) if not callable(validator): raise ValidationError( "design-research-analysis is installed but does not expose " "`integration.validate_experiment_events(...)`. Upgrade to the April " "compatibility branch." ) report = validator(events_csv_path) if getattr(report, "is_valid", True): return errors = getattr(report, "errors", ()) if isinstance(errors, Sequence) and not isinstance(errors, (str, bytes)): message = "; ".join(str(error) for error in errors) or "Unified table validation failed." else: message = "Unified table validation failed." raise ValidationError(message) def _load_analysis_validation_module() -> Any | None: """Return the analysis integration module when the April API is available.""" try: return importlib.import_module("design_research_analysis.integration") except ImportError as exc: try: importlib.import_module("design_research_analysis") except ImportError: return None raise ValidationError( "design-research-analysis is installed but does not expose the " "artifact-first `integration` module. Upgrade to the April compatibility " "branch." ) from exc def validate_unified_event_columns(event_rows: Sequence[dict[str, Any]]) -> list[str]: """Validate that event rows include required unified-event columns.""" errors: list[str] = [] for index, row in enumerate(event_rows): for column in EVENT_REQUIRED_COLUMNS: if column not in row: errors.append(f"events row {index} is missing required column '{column}'.") return errors