Skip to content

hydro_log

The hydro_log module provides logging utilities with rich formatting and file/console output capabilities.

Classes

HydroWarning

A class for handling and displaying hydrology-related warnings and messages with rich formatting.

1
2
3
4
5
class HydroWarning:
    def __init__(self)
    def no_directory(directory_name: str, message: Text = None) -> None
    def file_not_found(file_name: str, message: Text = None) -> None
    def operation_successful(operation_detail: str, message: Text = None) -> None

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from hydroutils import HydroWarning

warning = HydroWarning()

# Display directory not found warning
warning.no_directory("/path/to/missing/dir")

# Display file not found warning
warning.file_not_found("data.csv")

# Display success message
warning.operation_successful("Data processing complete")

Decorators

@hydro_logger

A class decorator that adds logging capabilities to a class.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from hydroutils import hydro_logger

@hydro_logger
class MyHydroClass:
    def process_data(self):
        self.logger.info("Starting data processing...")
        # Processing logic here
        self.logger.debug("Processing complete")

# The class now has both file and console logging
obj = MyHydroClass()
obj.process_data()  # Logs will be written to file and console

Features: - Automatically creates log directory in cache - Timestamps in log filenames - Both file (DEBUG level) and console (INFO level) output - Standard logging format with timestamp, module name, and log level

API Reference

Author: Wenyu Ouyang Date: 2023-10-25 20:07:14 LastEditTime: 2025-01-15 11:55:24 LastEditors: Wenyu Ouyang Description: Use rich to log: https://rich.readthedocs.io/en/latest/ FilePath: \hydroutils\hydroutils\hydro_log.py Copyright (c) 2023-2024 Wenyu Ouyang. All rights reserved.

HydroWarning

A class for displaying formatted warning messages using Rich console.

This class provides methods for displaying different types of warning messages with consistent formatting and color coding using the Rich library.

Attributes:

Name Type Description
console Console

Rich console instance for formatted output.

Source code in hydroutils/hydro_log.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class HydroWarning:
    """A class for displaying formatted warning messages using Rich console.

    This class provides methods for displaying different types of warning messages
    with consistent formatting and color coding using the Rich library.

    Attributes:
        console (Console): Rich console instance for formatted output.
    """

    def __init__(self):
        """Initialize HydroWarning with a Rich console instance."""
        self.console = Console()

    def no_directory(self, directory_name, message=None):
        """Display a warning message for a missing directory.

        Args:
            directory_name (str): Name of the missing directory.
            message (Text, optional): Custom warning message. If None, a default
                message will be created. Defaults to None.
        """
        if message is None:
            message = Text(
                f"There is no such directory: {directory_name}", style="bold red"
            )
        self.console.print(message)

    def file_not_found(self, file_name, message=None):
        """Display a warning message for a file that cannot be found.

        Args:
            file_name (str): Name of the file that could not be found.
            message (Text, optional): Custom warning message. If None, a default
                message will be created. Defaults to None.
        """
        if message is None:
            message = Text(
                f"We didn't find this file: {file_name}", style="bold yellow"
            )
        self.console.print(message)

    def operation_successful(self, operation_detail, message=None):
        """Display a success message for a completed operation.

        Args:
            operation_detail (str): Description of the successful operation.
            message (Text, optional): Custom success message. If None, a default
                message will be created. Defaults to None.
        """
        if message is None:
            message = Text(f"Operation Success: {operation_detail}", style="bold green")
        self.console.print(message)

__init__()

Initialize HydroWarning with a Rich console instance.

Source code in hydroutils/hydro_log.py
30
31
32
def __init__(self):
    """Initialize HydroWarning with a Rich console instance."""
    self.console = Console()

file_not_found(file_name, message=None)

Display a warning message for a file that cannot be found.

Parameters:

Name Type Description Default
file_name str

Name of the file that could not be found.

required
message Text

Custom warning message. If None, a default message will be created. Defaults to None.

None
Source code in hydroutils/hydro_log.py
48
49
50
51
52
53
54
55
56
57
58
59
60
def file_not_found(self, file_name, message=None):
    """Display a warning message for a file that cannot be found.

    Args:
        file_name (str): Name of the file that could not be found.
        message (Text, optional): Custom warning message. If None, a default
            message will be created. Defaults to None.
    """
    if message is None:
        message = Text(
            f"We didn't find this file: {file_name}", style="bold yellow"
        )
    self.console.print(message)

no_directory(directory_name, message=None)

Display a warning message for a missing directory.

Parameters:

Name Type Description Default
directory_name str

Name of the missing directory.

required
message Text

Custom warning message. If None, a default message will be created. Defaults to None.

None
Source code in hydroutils/hydro_log.py
34
35
36
37
38
39
40
41
42
43
44
45
46
def no_directory(self, directory_name, message=None):
    """Display a warning message for a missing directory.

    Args:
        directory_name (str): Name of the missing directory.
        message (Text, optional): Custom warning message. If None, a default
            message will be created. Defaults to None.
    """
    if message is None:
        message = Text(
            f"There is no such directory: {directory_name}", style="bold red"
        )
    self.console.print(message)

operation_successful(operation_detail, message=None)

Display a success message for a completed operation.

Parameters:

Name Type Description Default
operation_detail str

Description of the successful operation.

required
message Text

Custom success message. If None, a default message will be created. Defaults to None.

None
Source code in hydroutils/hydro_log.py
62
63
64
65
66
67
68
69
70
71
72
def operation_successful(self, operation_detail, message=None):
    """Display a success message for a completed operation.

    Args:
        operation_detail (str): Description of the successful operation.
        message (Text, optional): Custom success message. If None, a default
            message will be created. Defaults to None.
    """
    if message is None:
        message = Text(f"Operation Success: {operation_detail}", style="bold green")
    self.console.print(message)

hydro_logger(cls)

Class decorator that adds a configured logger to the decorated class.

This decorator sets up a logger with both file and console handlers. The file handler writes all logs (DEBUG and above) to a timestamped file in the cache directory, while the console handler shows INFO and above messages.

Parameters:

Name Type Description Default
cls

The class to be decorated.

required

Returns:

Type Description

The decorated class with an added logger attribute.

Example

@hydro_logger class MyClass: def my_method(self): self.logger.info("This will be logged")

Source code in hydroutils/hydro_log.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
def hydro_logger(cls):
    """Class decorator that adds a configured logger to the decorated class.

    This decorator sets up a logger with both file and console handlers. The file
    handler writes all logs (DEBUG and above) to a timestamped file in the cache
    directory, while the console handler shows INFO and above messages.

    Args:
        cls: The class to be decorated.

    Returns:
        The decorated class with an added logger attribute.

    Example:
        @hydro_logger
        class MyClass:
            def my_method(self):
                self.logger.info("This will be logged")
    """
    # Use the class name as the logger name
    logger_name = f"{cls.__module__}.{cls.__name__}"
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    cache_dir = get_cache_dir()
    log_dir = os.path.join(cache_dir, "logs")
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    log_file = os.path.join(log_dir, f"{logger_name}_{current_time}.log")
    # Check if handlers have already been added to avoid duplication
    if not logger.handlers:
        # Create a file handler to write logs to the specified file
        file_handler = logging.FileHandler(log_file)
        file_handler.setLevel(logging.DEBUG)

        # Create a console handler to output logs to the console (optional)
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.INFO)

        # set the format of the log
        formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        )
        file_handler.setFormatter(formatter)
        console_handler.setFormatter(formatter)

        # Add handlers to the logger
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)

    # Bind the logger to the class attribute
    cls.logger = logger
    return cls