UI & Terminal Output Helpers
Relevant source files
The following files were used as context for generating this wiki page:
The UI and Terminal Output system in dbt-common provides a standardized framework for generating human-readable logs, console formatting, and structured event messages. It bridges the gap between raw data processing and the end-user interface by providing utility functions for text tagging, event-driven printing, and specialized Jinja rendering for terminal display.
This system is designed to support various output levels—ranging from debugging and info to warnings—while ensuring that critical information remains visible even in restricted modes, such as "quiet" mode.
Event-Driven Terminal Output
The primary mechanism for terminal communication is the Event system. Events represent specific occurrences within the application lifecycle and define how they should be represented as strings for the console.
Event Level Hierarchy
Terminal output is categorized by severity levels, which determine visibility based on logger settings.
| Level | Purpose | Example Usage |
|---|---|---|
DebugLevel | Detailed diagnostic information | Retrying external calls, command execution details. |
InfoLevel | General operational status | Formatting separators, standard notes, print events. |
WarnLevel | Non-fatal issues requiring attention | Deprecations, behavior changes, custom config warnings. |
Sources: dbt_common/events/types.py:1-10, dbt_common/events/types.py:115-165
Specialized UI Events
Certain events are specifically tailored for UI control and terminal aesthetics:
- Formatting (Z017): Used for empty lines, heading separators, and console-only visual structural elements.
- Note (Z050): Unstructured text logs that are useful for human readers but not intended for machine parsing.
- PrintEvent (Z052): A high-priority event that bypasses standard formatting and is sent to stdout even if the logger is set to ERROR level. This is crucial for supporting
--quietmodes while still providing necessary output.
Sources: dbt_common/events/types.py:115-155
UI Tagging and Visual Helpers
UI tagging functions are used to wrap terminal text with visual indicators, such as warnings or error markers. These helpers ensure consistency across different output modules.
Warning and Error Tags
The system utilizes warning_tag and error_tag to highlight significant messages. For example, BehaviorChangeEvent uses a warning tag to inform users about upcoming changes and how to opt into them.
class BehaviorChangeEvent(WarnLevel):
def message(self) -> str:
return warning_tag(
f"{self.description}\n"
f"You may opt into the new behavior sooner by setting `flags.{self.flag_name}` to `True`.\n"
f"Visit {self.docs_url} for more information."
)
Sources: dbt_common/events/types.py:43-52, CHANGELOG.md:320-321
Secret Scrubbing in Output
To protect sensitive information, the UI system includes a scrubbing mechanism that prevents environment secrets from being printed to the terminal or logs.
The scrub_secrets function identifies strings starting with the SECRET_ENV_PREFIX and replaces them globally within any message before it is displayed or stored.
Sources: dbt_common/exceptions/base.py:10-21
Terminal Rendering with Jinja
The project uses Jinja2 to render complex terminal outputs, particularly for macros and documentation blocks. A specialized environment is maintained to handle terminal-specific filtering and type conversion.
Jinja Filters for UI
The system provides filters that dictate how data types are converted for display:
| Filter | Purpose |
|---|---|
as_text | Marks a value as a TextMarker to prevent numerical evaluation. |
as_bool | Ensures the value is treated as a boolean in the output. |
as_number | Forces numerical representation. |
is_list | A helper to verify list types within templates. |
Sources: dbt_common/clients/jinja.py:417-434
Block Extraction Logic
Before rendering, the UI system often needs to extract top-level blocks from template files (like docs or macro blocks) to determine what should be displayed to the user.
Error Formatting for Terminal
The system provides detailed formatting for exceptions to ensure they are actionable when printed to the terminal.
- Stack Traces:
DbtRuntimeErrorand its subclasses (likeCompilationErrororDatabaseError) include logic to process a "node stack," showing the sequence of calls (e.g., "in model X called by macro Y"). - Validation Errors: Specialized formatting for
jsonschemaerrors converts complex validation paths into readable strings likeat path [columns][0][name]: ....
Sources: dbt_common/exceptions/base.py:58-95, dbt_common/exceptions/base.py:115-135
Summary
The UI and Terminal Output Helpers in dbt-common provide a robust, event-driven architecture for user communication. By combining a structured event system with specialized Jinja rendering and strict secret scrubbing, the project ensures that terminal output is both informative and secure. Key features like the PrintEvent and Formatting events allow for fine-grained control over the console experience, even in restricted execution environments.