Description
In addition to the simple default behavior (Python's print
function → stdout), which is fine for CLI use, we should support programmatic invocations, where printing to stdout
doesn't make sense. We could do this with a "print" event/log instead, probably with a special level.
If we do go the logging route, we'd need to respect these flags:
--quiet
: suppress all log messages from stdout, except those with the special "print" level--no-print
: suppress all "print"-level log messages from stdout
Implementation options:
- In all current call sites for
print
, we add conditional logic that eitherprint
s, or fires an event specific to that call site. (E.g.CustomMacroPrint
,ListResult
) - We add a single new event type,
PrintMessage
. We swap out 1:1 all direct calls toprint
with a new custom "print" method, defined either inclients.system
or theevents
module, and define the conditional logic (to print or not to print) one time in that method.
Current call sites
There are three primary places in the codebase where we call print
today, plus a few miscellaneous others.
1. print
dbt-Jinja context member
a.k.a. the "codegen" use case
dbt-core/core/dbt/context/base.py
Lines 640 to 656 in 94d6d19
This should optionally fire an event, instead of just calling print
.
2. dbt list
We definitely need a way to make the results of list
available programmatically. But that might already be the case—we already both print
the results, and return them as the task result:
dbt-core/core/dbt/task/list.py
Lines 150 to 154 in 94d6d19
So when the new CLI/API supports list
(#5549), we should expect the list
results being returned like:
from dbt.cli.main import dbtRunner
dbt = dbtRunner()
results, success = dbt.invoke(['list', '--select', 'some_model+'])
# 'results' now contains the list of selected nodes
In the spirit of completeness, I think it makes sense to opt for sending a structured logging event for each list
result, instead of printing it to stdout (default). It should be possible to suppress those in-lieu-of-printing events via the --no-print
flag described above.
3. dbt debug
This is pretty clearly a case where we want actual events/logs, and not just text print
ed to stdout.
Already open in #5353
Proposed resolution in #6541
4. Misc other spots
In dbt init
— this is probably just an oversight, I believe there should be an event manager available:
dbt-core/core/dbt/task/init.py
Line 284 in 94d6d19
In our functional testing framework — nbd