Skip to content

logging

napt.logging

Logging interface for NAPT.

This module provides a configurable logging interface that library modules can use for output without depending on the CLI. The logger can be configured globally or passed as a parameter for better isolation.

The logger supports five output levels:

  • Step: Always printed (for progress indicators)
  • Info: Always printed (for notable events that are not warnings)
  • Warning: Always printed (for important warnings that users should see)
  • Verbose: Only printed when verbose mode is enabled
  • Debug: Only printed when debug mode is enabled (implies verbose)
Example

Configure global logger:

from napt.logging import get_logger, set_global_logger

logger = get_logger(verbose=True, debug=False)
set_global_logger(logger)

Use in library code:

from napt.logging import get_logger

logger = get_logger()
logger.step(1, 4, "Loading configuration...")
logger.info("PACKAGE", "Removing previous package: 144.0.0")
logger.warning("DETECTION", "Could not extract MSI metadata")
logger.verbose("STATE", "Loaded state from file")
logger.debug("VERSION", "Trying backend: msilib...")

Use with dependency injection:

def my_function(logger=None):
    if logger is None:
        logger = get_logger()
    logger.verbose("MODULE", "Processing...")
Note

The default logger is silent (verbose=False, debug=False), so library functions won't print anything unless explicitly configured. The CLI configures the global logger when commands are executed.

Logger

Bases: Protocol

Protocol for logger implementations.

Source code in napt/logging.py
class Logger(Protocol):
    """Protocol for logger implementations."""

    def step(self, step: int, total: int, message: str) -> None:
        """Print a step indicator for non-verbose mode.

        Args:
            step: Current step number (1-based).
            total: Total number of steps.
            message: Step description.
        """
        ...

    def info(self, prefix: str, message: str) -> None:
        """Print an informational message (always visible).

        Use for notable events that are not warnings — e.g., replacing a
        previous artifact, skipping a step for a known reason.

        Args:
            prefix: Message prefix (e.g., "PACKAGE", "BUILD").
            message: Informational message.
        """
        ...

    def warning(self, prefix: str, message: str) -> None:
        """Print a warning message (always visible).

        Args:
            prefix: Message prefix (e.g., "DETECTION", "BUILD").
            message: Warning message.
        """
        ...

    def verbose(self, prefix: str, message: str) -> None:
        """Print a verbose log message.

        Args:
            prefix: Message prefix (e.g., "STATE", "BUILD").
            message: Log message.
        """
        ...

    def debug(self, prefix: str, message: str) -> None:
        """Print a debug log message.

        Args:
            prefix: Message prefix (e.g., "VERSION", "HTTP").
            message: Log message.
        """
        ...

step

step(step: int, total: int, message: str) -> None

Print a step indicator for non-verbose mode.

Parameters:

Name Type Description Default
step int

Current step number (1-based).

required
total int

Total number of steps.

required
message str

Step description.

required
Source code in napt/logging.py
def step(self, step: int, total: int, message: str) -> None:
    """Print a step indicator for non-verbose mode.

    Args:
        step: Current step number (1-based).
        total: Total number of steps.
        message: Step description.
    """
    ...

info

info(prefix: str, message: str) -> None

Print an informational message (always visible).

Use for notable events that are not warnings — e.g., replacing a previous artifact, skipping a step for a known reason.

Parameters:

Name Type Description Default
prefix str

Message prefix (e.g., "PACKAGE", "BUILD").

required
message str

Informational message.

required
Source code in napt/logging.py
def info(self, prefix: str, message: str) -> None:
    """Print an informational message (always visible).

    Use for notable events that are not warnings — e.g., replacing a
    previous artifact, skipping a step for a known reason.

    Args:
        prefix: Message prefix (e.g., "PACKAGE", "BUILD").
        message: Informational message.
    """
    ...

warning

warning(prefix: str, message: str) -> None

Print a warning message (always visible).

Parameters:

Name Type Description Default
prefix str

Message prefix (e.g., "DETECTION", "BUILD").

required
message str

Warning message.

required
Source code in napt/logging.py
def warning(self, prefix: str, message: str) -> None:
    """Print a warning message (always visible).

    Args:
        prefix: Message prefix (e.g., "DETECTION", "BUILD").
        message: Warning message.
    """
    ...

verbose

verbose(prefix: str, message: str) -> None

Print a verbose log message.

Parameters:

Name Type Description Default
prefix str

Message prefix (e.g., "STATE", "BUILD").

required
message str

Log message.

required
Source code in napt/logging.py
def verbose(self, prefix: str, message: str) -> None:
    """Print a verbose log message.

    Args:
        prefix: Message prefix (e.g., "STATE", "BUILD").
        message: Log message.
    """
    ...

debug

debug(prefix: str, message: str) -> None

Print a debug log message.

Parameters:

Name Type Description Default
prefix str

Message prefix (e.g., "VERSION", "HTTP").

required
message str

Log message.

required
Source code in napt/logging.py
def debug(self, prefix: str, message: str) -> None:
    """Print a debug log message.

    Args:
        prefix: Message prefix (e.g., "VERSION", "HTTP").
        message: Log message.
    """
    ...

DefaultLogger

Default logger implementation that prints to stdout.

This logger respects verbose and debug flags and formats output consistently with the CLI output format.

Source code in napt/logging.py
class DefaultLogger:
    """Default logger implementation that prints to stdout.

    This logger respects verbose and debug flags and formats output
    consistently with the CLI output format.
    """

    def __init__(self, verbose: bool = False, debug: bool = False) -> None:
        """Initialize logger with verbosity settings.

        Args:
            verbose: If True, print verbose messages.
            debug: If True, print debug messages (implies verbose).
        """
        self._verbose = verbose or debug
        self._debug = debug

    def step(self, step: int, total: int, message: str) -> None:
        """Print a step indicator for non-verbose mode."""
        print(f"[{step}/{total}] {message}")

    def info(self, prefix: str, message: str) -> None:
        """Print an informational message (always visible)."""
        print(f"[{prefix}] {message}")

    def warning(self, prefix: str, message: str) -> None:
        """Print a warning message (always visible)."""
        print(f"[{prefix}] {message}")

    def verbose(self, prefix: str, message: str) -> None:
        """Print a verbose log message (only when verbose mode is active)."""
        if self._verbose:
            print(f"[{prefix}] {message}")

    def debug(self, prefix: str, message: str) -> None:
        """Print a debug log message (only when debug mode is active)."""
        if self._debug:
            print(f"[{prefix}] {message}")

__init__

__init__(verbose: bool = False, debug: bool = False) -> None

Initialize logger with verbosity settings.

Parameters:

Name Type Description Default
verbose bool

If True, print verbose messages.

False
debug bool

If True, print debug messages (implies verbose).

False
Source code in napt/logging.py
def __init__(self, verbose: bool = False, debug: bool = False) -> None:
    """Initialize logger with verbosity settings.

    Args:
        verbose: If True, print verbose messages.
        debug: If True, print debug messages (implies verbose).
    """
    self._verbose = verbose or debug
    self._debug = debug

step

step(step: int, total: int, message: str) -> None

Print a step indicator for non-verbose mode.

Source code in napt/logging.py
def step(self, step: int, total: int, message: str) -> None:
    """Print a step indicator for non-verbose mode."""
    print(f"[{step}/{total}] {message}")

info

info(prefix: str, message: str) -> None

Print an informational message (always visible).

Source code in napt/logging.py
def info(self, prefix: str, message: str) -> None:
    """Print an informational message (always visible)."""
    print(f"[{prefix}] {message}")

warning

warning(prefix: str, message: str) -> None

Print a warning message (always visible).

Source code in napt/logging.py
def warning(self, prefix: str, message: str) -> None:
    """Print a warning message (always visible)."""
    print(f"[{prefix}] {message}")

verbose

verbose(prefix: str, message: str) -> None

Print a verbose log message (only when verbose mode is active).

Source code in napt/logging.py
def verbose(self, prefix: str, message: str) -> None:
    """Print a verbose log message (only when verbose mode is active)."""
    if self._verbose:
        print(f"[{prefix}] {message}")

debug

debug(prefix: str, message: str) -> None

Print a debug log message (only when debug mode is active).

Source code in napt/logging.py
def debug(self, prefix: str, message: str) -> None:
    """Print a debug log message (only when debug mode is active)."""
    if self._debug:
        print(f"[{prefix}] {message}")

SilentLogger

Logger that suppresses all output.

Useful for programmatic usage when output is not desired.

Source code in napt/logging.py
class SilentLogger:
    """Logger that suppresses all output.

    Useful for programmatic usage when output is not desired.
    """

    def step(self, step: int, total: int, message: str) -> None:
        """Suppress step output."""
        pass

    def info(self, prefix: str, message: str) -> None:
        """Suppress info output."""
        pass

    def warning(self, prefix: str, message: str) -> None:
        """Suppress warning output."""
        pass

    def verbose(self, prefix: str, message: str) -> None:
        """Suppress verbose output."""
        pass

    def debug(self, prefix: str, message: str) -> None:
        """Suppress debug output."""
        pass

step

step(step: int, total: int, message: str) -> None

Suppress step output.

Source code in napt/logging.py
def step(self, step: int, total: int, message: str) -> None:
    """Suppress step output."""
    pass

info

info(prefix: str, message: str) -> None

Suppress info output.

Source code in napt/logging.py
def info(self, prefix: str, message: str) -> None:
    """Suppress info output."""
    pass

warning

warning(prefix: str, message: str) -> None

Suppress warning output.

Source code in napt/logging.py
def warning(self, prefix: str, message: str) -> None:
    """Suppress warning output."""
    pass

verbose

verbose(prefix: str, message: str) -> None

Suppress verbose output.

Source code in napt/logging.py
def verbose(self, prefix: str, message: str) -> None:
    """Suppress verbose output."""
    pass

debug

debug(prefix: str, message: str) -> None

Suppress debug output.

Source code in napt/logging.py
def debug(self, prefix: str, message: str) -> None:
    """Suppress debug output."""
    pass

get_logger

get_logger(verbose: bool = False, debug: bool = False) -> Logger

Get a logger instance with specified verbosity.

Parameters:

Name Type Description Default
verbose bool

If True, logger will print verbose messages.

False
debug bool

If True, logger will print debug messages (implies verbose).

False

Returns:

Type Description
Logger

A logger instance configured with the specified verbosity.

Example

Get a verbose logger:

logger = get_logger(verbose=True)
logger.verbose("MODULE", "Processing...")

Get a debug logger:

logger = get_logger(debug=True)
logger.debug("MODULE", "Debug info...")

Source code in napt/logging.py
def get_logger(verbose: bool = False, debug: bool = False) -> Logger:
    """Get a logger instance with specified verbosity.

    Args:
        verbose: If True, logger will print verbose messages.
        debug: If True, logger will print debug messages (implies verbose).

    Returns:
        A logger instance configured with the specified verbosity.

    Example:
        Get a verbose logger:
            ```python
            logger = get_logger(verbose=True)
            logger.verbose("MODULE", "Processing...")
            ```

        Get a debug logger:
            ```python
            logger = get_logger(debug=True)
            logger.debug("MODULE", "Debug info...")
            ```
    """
    return DefaultLogger(verbose=verbose, debug=debug)

get_global_logger

get_global_logger() -> Logger

Get the global logger instance.

Returns:

Type Description
Logger

The current global logger instance.

Note

The default global logger is silent. Use set_global_logger() to configure it, or pass a logger instance directly to functions.

Source code in napt/logging.py
def get_global_logger() -> Logger:
    """Get the global logger instance.

    Returns:
        The current global logger instance.

    Note:
        The default global logger is silent. Use set_global_logger() to
        configure it, or pass a logger instance directly to functions.
    """
    return _global_logger

set_global_logger

set_global_logger(logger: Logger) -> None

Set the global logger instance.

Parameters:

Name Type Description Default
logger Logger

Logger instance to use as the global logger.

required
Example

Configure global logger from CLI:

from napt.logging import get_logger, set_global_logger

logger = get_logger(verbose=args.verbose, debug=args.debug)
set_global_logger(logger)

Note

This affects all library functions that use get_logger() without passing a logger instance. For better isolation, pass logger instances directly to functions instead of using the global logger.

Source code in napt/logging.py
def set_global_logger(logger: Logger) -> None:
    """Set the global logger instance.

    Args:
        logger: Logger instance to use as the global logger.

    Example:
        Configure global logger from CLI:
            ```python
            from napt.logging import get_logger, set_global_logger

            logger = get_logger(verbose=args.verbose, debug=args.debug)
            set_global_logger(logger)
            ```

    Note:
        This affects all library functions that use get_logger() without
        passing a logger instance. For better isolation, pass logger
        instances directly to functions instead of using the global logger.
    """
    global _global_logger
    _global_logger = logger