Logging and warnings¶
raitap_log is the single facade for logging.getLogger(__name__) + warnings.warn. Don't import logging or warnings in feature code.
from raitap import raitap_log
raitap_log.info("Running model forward pass...")
raitap_log.warn("Labels file is empty; falling back to predictions as targets.")
raitap_log.debug("Resolved %d sample ids", len(sample_ids))
raitap_log.exception("Tracker instantiation failed for target %r", target_path)
Lives at src/raitap/utils/log.py, re-exported as raitap.raitap_log.
Methods¶
Method |
Pipeline |
Use for |
|---|---|---|
|
|
Any warning. User-config issues + operational signals. Panel-rendered with module chip, suppressible via |
|
|
Normal operational events (phase started, file written). |
|
|
Verbose diagnostics off by default. |
|
|
Recoverable errors logged before fallback. Does not raise. |
|
|
Inside |
|
|
Process-ending failures. |
|
|
Silence known-noise library warnings. Prefer the |
Caller-aware: .info / .debug / .error / .exception / .critical route to logging.getLogger(<caller's __name__>) via stack inspection — no logger = … boilerplate needed.
One warning verb¶
Exactly one: .warn. Covers user-config issues AND operational signals.
If you want something more dramatic, ask:
Failure? →
.error(or.exceptioninsideexcept).Routine progress? →
.info.
.warn covers everything in between. If you have a traceback, you almost always want .exception instead.
Raising errors¶
Don't go through raitap_log — use plain raise for raitap-originated errors:
raise ValueError(
f"Data source {source!r} does not exist.\n"
"Expected a URL, an existing local path, or a named demo sample."
)
For wrapped third-party calls (captum / shap / foolbox / torchattacks), use the adapter's self._rethrow() helper. It pulls library, the family group, and the error_patterns map straight from the adapter's @adapters.<family>(...) decoration — no kwargs needed at the call site:
# src/raitap/transparency/explainers/shap_explainer.py
from raitap import adapters
@adapters.transparency(
registry_name="shap",
library="shap",
error_patterns={
r"BackwardHookFunctionBackward is a view": (
"DeepExplainer can fail on PyTorch models that use SiLU "
"activations (for example EfficientNet variants). Use "
"alternatives like GradientExplainer."
),
},
algorithm_registry={...},
)
class ShapExplainer(AttributionOnlyExplainer):
def compute_attributions(self, model, inputs, **kwargs):
shap = self._lazy_import()
with self._rethrow():
return getattr(shap, self.algorithm)(model, ...).shap_values(inputs)
The original exception is preserved on __cause__, so the raw traceback stays for debugging — only the user-facing top is rewritten. RaitapError subclasses render with the same Module · via <lib> · View docs chips as warnings.
Module attribution¶
The rich handler decorates warnings with a module chip (Metrics, Robustness, Transparency, …). Inferred from the call site via frame walking — usually correct.
When the logical module differs from the file path, pass module= explicitly:
# src/raitap/_adapters.py — top-level file, logically a deps concern.
raitap_log.warn(
f"Skipping plugin {ep.name!r}: {why}",
module=Module.deps,
)
Module is a StrEnum (one member per top-level raitap directory). Use the enum, not a raw string.
Suppressing third-party noise¶
Use the suppress_warnings= decorator kwarg on the adapter, not a module-level raitap_log.suppress call. The decorator installs the filter at registration time (same as a module-level call would), but the noise spec stays colocated with the adapter that owns it:
from raitap import adapters
@adapters.transparency(
registry_name="captum",
library="captum",
suppress_warnings=[
# Captum emits this on every run when inputs don't already require
# gradients. Auto-fixes the issue → pure noise. Scope module=captum
# so unrelated UserWarnings with matching text aren't hidden.
(r"Input Tensor.*required_grads", UserWarning, r"captum.*"),
],
algorithm_registry={...},
)
class CaptumExplainer(AttributionOnlyExplainer): ...
Always scope module= to the wrapped library so unrelated UserWarnings with the same text aren't hidden.
Where the infrastructure lives¶
src/raitap/utils/log.py—_RaitapLogclass +raitap_logsingleton. Owns the thread-local diagnostic queue bridgingwarnings.formatwarningto the rich handler.src/raitap/utils/diagnostics.py—Moduleenum + frame-walking classifier + third-party library detection. The library set is auto-populated by_register_corefrom each@register_*_adapter(..., library="...")decoration and stored atraitap._adapters.THIRD_PARTY_LIBS(grouped by adapter family).src/raitap/utils/errors.py—RaitapError/AdapterError, traceback-walking diagnostic resolver,rethrowcontext manager.src/raitap/utils/colour.py— two-shade palette + RichTheme. Edit here when adding/rebalancing colours.src/raitap/utils/console.py—RichHandlersubclass +print_failure_panel. Callslogging.captureWarnings(True)so external sinks see warnings.
Touching that code? Expect to update src/raitap/utils/tests/test_log.py, test_diagnostics.py, test_errors.py, test_console_errors.py.