Legal-RAG / scripts /quiet.py
flora-l's picture
recreate the space for demo
ddbc0c8
"""Quiet-mode utilities for notebooks and demos.
Goals:
- Suppress noisy logs (INFO/DEBUG), progress bars, and common framework warnings.
- Keep meaningful outputs (tables/figures/explicit prints) visible.
- Provide an opt-in context manager to silence extremely noisy calls.
Usage:
from scripts.quiet import install_quiet
install_quiet()
For a particularly noisy block:
from scripts.quiet import suppress_output
with suppress_output():
do_noisy_work()
"""
from __future__ import annotations
import logging
import os
import sys
import warnings
from contextlib import contextmanager
from typing import Iterator, Optional
def install_quiet(
*,
python_warnings: bool = True,
logging_level: int = logging.ERROR,
silence_tqdm: bool = True,
silence_hf_progress: bool = True,
silence_tensorflow: bool = True,
message_only_loggers: Optional[list[str]] = ['legalrag.retrieval.graph_store'],
silence_colbert_stdout: bool = True,
) -> None:
"""Install a set of conservative defaults to reduce notebook noise.
Parameters
----------
python_warnings:
If True, suppresses common warning categories that frequently clutter demo notebooks.
logging_level:
Root logging level to set (default ERROR). This suppresses INFO/DEBUG logs such as
'2025-.. - __main__ - INFO - ...'.
silence_tqdm:
If True, tries to disable tqdm progress bars via environment variables.
silence_hf_progress:
If True, disables Hugging Face advisory warnings and some progress output.
silence_tensorflow:
If True, reduces TensorFlow / XLA / absl logging chatter where possible.
"""
if python_warnings:
# The jieba 'invalid escape sequence' lines come from SyntaxWarning during import.
warnings.filterwarnings("ignore", category=SyntaxWarning)
# Reduce general deprecation/runtime warnings that are rarely useful in demos.
warnings.filterwarnings("ignore", category=DeprecationWarning)
warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=UserWarning, message=r".*progress bar.*")
# add more filters here
# Root logger: suppress INFO/DEBUG timestamped lines.
logging.basicConfig(level=logging_level)
logging.getLogger().setLevel(logging_level)
for name in [
"legalrag",
"legalrag.retrieval",
"legalrag.retrieval.graph_store",
"legalrag.retrieval.hybrid_retriever",
"legalrag.retrieval.bm25_retriever",
"legalrag.pipeline.rag_pipeline",
"legalrag.pipeline",
"legalrag.api",
"jieba",
"transformers",
"sentence_transformers",
"faiss",
"tensorflow",
"torch",
"urllib3",
]:
logging.getLogger(name).setLevel(logging_level)
for name in list(logging.root.manager.loggerDict.keys()):
if name == "legalrag" or name.startswith("legalrag."):
logging.getLogger(name).setLevel(logging_level)
if message_only_loggers:
for name in message_only_loggers:
lg = logging.getLogger(name)
lg.setLevel(logging.INFO)
for h in lg.handlers:
h.setFormatter(logging.Formatter("%(message)s"))
lg.propagate = False
if silence_colbert_stdout:
try:
from legalrag.retrieval.colbert_retriever import ColBERTRetriever
_orig_init = ColBERTRetriever._init_searcher
_orig_search = ColBERTRetriever.search
def _init_quiet(self):
with suppress_output():
return _orig_init(self)
def _search_quiet(self, *args, **kwargs):
with suppress_output():
return _orig_search(self, *args, **kwargs)
ColBERTRetriever._init_searcher = _init_quiet
ColBERTRetriever.search = _search_quiet
except Exception:
pass
if silence_tqdm:
# Many libs respect these toggles.
os.environ.setdefault("TQDM_DISABLE", "1")
if silence_hf_progress:
os.environ.setdefault("TRANSFORMERS_NO_ADVISORY_WARNINGS", "1")
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
os.environ.setdefault("HF_HUB_DISABLE_TELEMETRY", "1")
os.environ.setdefault("TRANSFORMERS_NO_TORCHVISION", "1")
os.environ.setdefault("DISABLE_TORCHVISION", "1")
os.environ.setdefault("TRANSFORMERS_NO_IMAGE_PROCESSING", "1")
if silence_tensorflow:
# TensorFlow C++ log level: 0 = all, 1 = INFO, 2 = WARNING, 3 = ERROR
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "3")
os.environ.setdefault("TRANSFORMERS_NO_TF", "1")
os.environ.setdefault("USE_TF", "0")
# If transformers is imported, we can try to disable its verbosity.
try:
from transformers.utils import logging as hf_logging
hf_logging.set_verbosity_error()
hf_logging.disable_progress_bar()
except Exception:
pass
@contextmanager
def suppress_output(*, stdout: bool = True, stderr: bool = True) -> Iterator[None]:
"""Temporarily redirect stdout/stderr to os.devnull.
Use this sparingly—only for extremely noisy calls (e.g., one-time index builds).
"""
devnull = open(os.devnull, "w")
old_stdout: Optional[object] = None
old_stderr: Optional[object] = None
try:
if stdout:
old_stdout = sys.stdout
sys.stdout = devnull
if stderr:
old_stderr = sys.stderr
sys.stderr = devnull
yield
finally:
try:
if stdout and old_stdout is not None:
sys.stdout = old_stdout
if stderr and old_stderr is not None:
sys.stderr = old_stderr
finally:
devnull.close()