Output System#
Structured output system for CLI runs. Provides event-driven messaging, verbosity-filtered rendering, progress tracking, and deterministic end-of-run summaries.
The live terminal output layer now coordinates renderer writes with active
spinners and progress bars so workflow events do not bleed into the progress
line. For Nipype execution, WorkflowProgress exposes an overall node-level
progress bar that can be driven from scheduler status callbacks.
The package re-exports the most commonly used output classes, while the canonical API documentation lives on the concrete submodules below.
thesis.core.output.events#
Event system for structured output in the thesis framework.
Provides an event bus that decouples event emission from rendering. All executor/tool output is normalized into structured events, which are then filtered by verbosity and rendered by the output layer.
Example
>>> from thesis.core.output.events import get_event_bus, EventLevel
>>> bus = get_event_bus()
>>> bus.emit("Workflow started", level=EventLevel.IMPORTANT)
- class thesis.core.output.events.EventLevel[source]#
Bases:
IntEnumEvent importance levels, ordered from most to least critical.
ERROR: Failures that stop processing.
WARNING: Issues that may affect outcome but do not stop processing.
IMPORTANT: Key milestones – tool starts/completions, file changes, build/test results, skipped actions.
INFO: Detailed informational messages (full tool logs, timing, etc.).
DEBUG: Internal implementation details.
Default output mode shows ERROR, WARNING, IMPORTANT. Verbose mode shows everything. Quiet mode shows ERROR only plus the final result.
- ERROR = 50#
- WARNING = 40#
- IMPORTANT = 30#
- INFO = 20#
- DEBUG = 10#
- __new__(value)#
- class thesis.core.output.events.Event[source]#
Bases:
objectA structured output event emitted during pipeline execution.
- Variables:
message – Human-readable event description.
level – Importance level controlling visibility.
timestamp – Unix timestamp when the event was created.
category – Optional grouping tag (e.g.
"workflow","tool","file","test").patient_id – Patient this event relates to, if any.
metadata – Arbitrary key-value data attached to the event.
- Parameters:
- level: EventLevel = 20#
- class thesis.core.output.events.EventBus[source]#
Bases:
objectCentral event pipeline that decouples emission from rendering.
Listeners subscribe to receive events and can filter by minimum level. The bus is thread-safe: events can be emitted from worker threads while the main thread renders output.
Example
>>> bus = EventBus() >>> bus.subscribe(lambda e: print(e.message)) >>> bus.emit("hello")
- Parameters:
max_events (
int)
- emit(message, *, level=EventLevel.INFO, category='', patient_id='', metadata=None)[source]#
Create and dispatch an event to all listeners.
- Parameters:
- Return type:
- Returns:
The created
Eventinstance.
- get_events(min_level=EventLevel.DEBUG, category=None, patient_id=None)[source]#
Return stored events matching the given filters.
- Parameters:
min_level (
EventLevel) – Minimum importance level to include.category (
Optional[str]) – If set, only return events with this category.patient_id (
Optional[str]) – If set, only return events for this patient.
- Return type:
- Returns:
List of matching events in chronological order.
thesis.core.output.modes#
Output mode configuration for the thesis framework.
Defines the verbosity levels, summary detail, and output format settings that control what the user sees during and after a run.
Example
>>> from thesis.core.output.modes import OutputConfig, OutputMode
>>> cfg = OutputConfig(mode=OutputMode.VERBOSE)
>>> cfg.min_event_level
EventLevel.DEBUG
- class thesis.core.output.modes.OutputMode[source]#
-
Verbosity level for console output.
QUIET: errors and final result only.
NORMAL: concise, human-friendly progress and key events.
VERBOSE: full informational logs, timing, debug context.
- QUIET = 'quiet'#
- NORMAL = 'normal'#
- VERBOSE = 'verbose'#
- __new__(value)#
- class thesis.core.output.modes.SummaryDetail[source]#
-
Level of detail in the end-of-run summary.
OFF: no summary printed.
COMPACT: one-line status + 3-6 key bullets.
FULL: expanded summary with all metadata.
- OFF = 'off'#
- COMPACT = 'compact'#
- FULL = 'full'#
- __new__(value)#
- class thesis.core.output.modes.OutputFormat[source]#
-
Output serialization format.
HUMAN: colored/styled text for interactive terminals.
JSON: machine-readable JSON lines (one object per event/summary).
- HUMAN = 'human'#
- JSON = 'json'#
- __new__(value)#
- class thesis.core.output.modes.OutputConfig[source]#
Bases:
BaseModelConfiguration for the output system.
Controls verbosity, summary detail, progress display, and format. CLI flags override values set here.
- Variables:
mode – Verbosity level.
summary – Summary detail level.
progress – Whether to show progress bars/spinners.
Nonemeans auto-detect (enabled for TTY, disabled otherwise).output_format – Serialization format.
- Parameters:
data (
Any)
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- mode: OutputMode#
- summary: SummaryDetail#
- output_format: OutputFormat#
- property min_event_level: EventLevel#
Minimum event level to display in the current mode.
thesis.core.output.summary#
Structured summary models for run results.
Provides Pydantic models for single-run and batch-run summaries that are populated during execution from events and execution metadata. Summaries are deterministic, structured, and serializable to both human-readable text and JSON.
Example
>>> from thesis.core.output.summary import RunSummary, RunStatus
>>> summary = RunSummary(
... patient_id="P001",
... workflow="hcp",
... status=RunStatus.SUCCESS,
... elapsed_seconds=123.4,
... )
- class thesis.core.output.summary.RunStatus[source]#
-
Final status of a single patient run.
SUCCESS: completed without errors.
PARTIAL: some steps completed, others failed or were skipped.
FAILED: processing failed with an error.
BLOCKED: could not start (e.g. preflight check failure, missing data).
SKIPPED: intentionally not run (e.g. dry run, user cancellation).
- SUCCESS = 'success'#
- PARTIAL = 'partial'#
- FAILED = 'failed'#
- BLOCKED = 'blocked'#
- SKIPPED = 'skipped'#
- __new__(value)#
- class thesis.core.output.summary.RunResult[source]#
Bases:
BaseModelDetailed result for a single patient run.
Populated incrementally during execution and used to build the final
RunSummary.- Variables:
patient_id – Patient identifier.
status – Final run status.
elapsed_seconds – Wall-clock duration in seconds.
workflow – Workflow name that was executed.
error_message – Primary failure reason, if any.
error_type – Exception class name, if any.
error_history – Per-attempt failure messages in order (one entry per failed retry attempt), used to show error progression across retries.
warnings – Warning messages collected during the run.
steps_completed – Names of successfully completed steps.
steps_failed – Names of steps that failed.
files_changed – Paths of files created or modified.
commands_run – External commands executed (e.g. FSL, ANTs).
retry_count – Number of retries attempted.
suggested_next_step – Actionable suggestion for the user.
metadata – Arbitrary extra data.
- Parameters:
data (
Any)
- class thesis.core.output.summary.RunSummary[source]#
Bases:
BaseModelStructured summary of a single patient run.
Built from a
RunResultafter execution completes. Contains the information needed to render the compact footer shown to the user.- Variables:
patient_id – Patient identifier.
workflow – Workflow name.
status – Final outcome.
elapsed_seconds – Wall-clock duration.
headline – One-line status headline (e.g.
"SUCCESS hcp P001 2m 13s").bullets – Key summary bullets (3-6 items).
next_step – Optional suggested next action.
result – Full result data for verbose/JSON output.
- Parameters:
data (
Any)
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class thesis.core.output.summary.BatchSummary[source]#
Bases:
BaseModelAggregated summary for a batch of patient runs.
Collects child
RunSummaryobjects and computes aggregate statistics for the batch-level footer.- Variables:
workflow – Workflow name.
total – Total number of patient runs.
succeeded – Count of successful runs.
partial – Count of partially successful runs.
failed – Count of failed runs.
blocked – Count of blocked runs.
skipped – Count of skipped runs.
total_elapsed_seconds – Total wall-clock time for the batch.
avg_elapsed_seconds – Average per-patient duration.
retries – Total retries across all patients.
run_summaries – Per-patient summaries in execution order.
failure_reasons – Grouped failure reasons with patient lists.
suggested_follow_up – Actionable follow-up suggestion.
- Parameters:
data (
Any)
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- run_summaries: List[RunSummary]#
thesis.core.output.progress#
Progress tracking protocol for the thesis framework.
Provides a Protocol for node-level progress tracking that allows different progress bar implementations to be used interchangeably.
- class thesis.core.output.progress.NodeProgressProtocol[source]#
Bases:
ProtocolProtocol for node-level progress tracking.
Any class that implements
node_started,node_finished,start, andstopcan be used as a node progress tracker. This allows Click’s progressbar wrapper (ClickNodeProgress) to be used interchangeably.- __init__(*args, **kwargs)#
thesis.core.output.renderer#
Output rendering for the thesis framework.
Renders events, summaries, and progress to the terminal or JSON. Handles color, alignment, and non-TTY fallback behavior.
The renderer subscribes to the EventBus and filters events
by the configured verbosity level before printing them.
Example
>>> from thesis.core.output.renderer import OutputRenderer
>>> from thesis.core.output.modes import OutputConfig
>>> renderer = OutputRenderer(OutputConfig())
>>> renderer.render_run_summary(summary)
- class thesis.core.output.renderer.OutputRenderer[source]#
Bases:
objectRenders structured output to the terminal or as JSON.
Connects to the
EventBusand prints events that pass the verbosity filter. Also provides methods for rendering run and batch summaries.- Parameters:
- render_run_summary(summary)[source]#
Render a single-run summary footer.
- Parameters:
summary (
RunSummary) – The run summary to render.- Return type:
- render_batch_summary(batch)[source]#
Render a batch summary footer.
- Parameters:
batch (
BatchSummary) – The batch summary to render.- Return type: