ortools.math_opt.python.message_callback

Definition and tools for message callbacks.

Message callbacks are used to get the text messages emitted by solvers during the solve.

Typical usage example:

# Print messages to stdout. result = solve.solve( model, parameters.SolverType.GSCIP, msg_cb=message_callback.printer_message_callback(prefix='[solver] '))

# Log messages with absl.logging. result = solve.solve( model, parameters.SolverType.GSCIP, msg_cb=lambda msgs: message_callback.log_messages( msgs, prefix='[solver] '))

  1# Copyright 2010-2024 Google LLC
  2# Licensed under the Apache License, Version 2.0 (the "License");
  3# you may not use this file except in compliance with the License.
  4# You may obtain a copy of the License at
  5#
  6#     http://www.apache.org/licenses/LICENSE-2.0
  7#
  8# Unless required by applicable law or agreed to in writing, software
  9# distributed under the License is distributed on an "AS IS" BASIS,
 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11# See the License for the specific language governing permissions and
 12# limitations under the License.
 13
 14"""Definition and tools for message callbacks.
 15
 16Message callbacks are used to get the text messages emitted by solvers during
 17the solve.
 18
 19  Typical usage example:
 20
 21  # Print messages to stdout.
 22  result = solve.solve(
 23      model, parameters.SolverType.GSCIP,
 24      msg_cb=message_callback.printer_message_callback(prefix='[solver] '))
 25
 26  # Log messages with absl.logging.
 27  result = solve.solve(
 28      model, parameters.SolverType.GSCIP,
 29      msg_cb=lambda msgs: message_callback.log_messages(
 30          msgs, prefix='[solver] '))
 31"""
 32
 33import sys
 34import threading
 35from typing import Callable, List, Sequence, TextIO
 36
 37from absl import logging
 38
 39SolveMessageCallback = Callable[[Sequence[str]], None]
 40
 41
 42def printer_message_callback(
 43    *, file: TextIO = sys.stdout, prefix: str = ""
 44) -> SolveMessageCallback:
 45    """Returns a message callback that prints to a file.
 46
 47    It prints its output to the given text file, prefixing each line with the
 48    given prefix.
 49
 50    For each call to the returned message callback, the output_stream is flushed.
 51
 52    Args:
 53      file: The file to print to. It prints to stdout by default.
 54      prefix: The prefix to print in front of each line.
 55
 56    Returns:
 57      A function matching the expected signature for message callbacks.
 58    """
 59    mutex = threading.Lock()
 60
 61    def callback(messages: Sequence[str]) -> None:
 62        with mutex:
 63            for message in messages:
 64                file.write(prefix)
 65                file.write(message)
 66                file.write("\n")
 67            file.flush()
 68
 69    return callback
 70
 71
 72def log_messages(
 73    messages: Sequence[str], *, level: int = logging.INFO, prefix: str = ""
 74) -> None:
 75    """Logs the input messages from a message callback using absl.logging.log().
 76
 77    It logs each line with the given prefix. It setups absl.logging so that the
 78    logs use the file name and line of the caller of this function.
 79
 80      Typical usage example:
 81
 82      result = solve.solve(
 83          model, parameters.SolverType.GSCIP,
 84          msg_cb=lambda msgs: message_callback.log_messages(
 85              msgs, prefix='[solver] '))
 86
 87    Args:
 88      messages: The messages received in the message callback (typically a lambda
 89        function in the caller code).
 90      level: One of absl.logging.(DEBUG|INFO|WARNING|ERROR|FATAL).
 91      prefix: The prefix to print in front of each line.
 92    """
 93    for message in messages:
 94        logging.log(level, "%s%s", prefix, message)
 95
 96
 97logging.ABSLLogger.register_frame_to_skip(__file__, log_messages.__name__)
 98
 99
100def vlog_messages(messages: Sequence[str], level: int, *, prefix: str = "") -> None:
101    """Logs the input messages from a message callback using absl.logging.vlog().
102
103    It logs each line with the given prefix. It setups absl.logging so that the
104    logs use the file name and line of the caller of this function.
105
106      Typical usage example:
107
108      result = solve.solve(
109          model, parameters.SolverType.GSCIP,
110          msg_cb=lambda msgs: message_callback.vlog_messages(
111              msgs, 1, prefix='[solver] '))
112
113    Args:
114      messages: The messages received in the message callback (typically a lambda
115        function in the caller code).
116      level: The verbose log level, e.g. 1, 2...
117      prefix: The prefix to print in front of each line.
118    """
119    for message in messages:
120        logging.vlog(level, "%s%s", prefix, message)
121
122
123logging.ABSLLogger.register_frame_to_skip(__file__, vlog_messages.__name__)
124
125
126def list_message_callback(sink: List[str]) -> SolveMessageCallback:
127    """Returns a message callback that logs messages to a list.
128
129    Args:
130      sink: The list to append messages to.
131
132    Returns:
133      A function matching the expected signature for message callbacks.
134    """
135    mutex = threading.Lock()
136
137    def callback(messages: Sequence[str]) -> None:
138        with mutex:
139            for message in messages:
140                sink.append(message)
141
142    return callback
SolveMessageCallback = typing.Callable[[typing.Sequence[str]], NoneType]
def printer_message_callback( *, file: <class 'TextIO'> = <_io.StringIO object>, prefix: str = '') -> Callable[[Sequence[str]], NoneType]:
43def printer_message_callback(
44    *, file: TextIO = sys.stdout, prefix: str = ""
45) -> SolveMessageCallback:
46    """Returns a message callback that prints to a file.
47
48    It prints its output to the given text file, prefixing each line with the
49    given prefix.
50
51    For each call to the returned message callback, the output_stream is flushed.
52
53    Args:
54      file: The file to print to. It prints to stdout by default.
55      prefix: The prefix to print in front of each line.
56
57    Returns:
58      A function matching the expected signature for message callbacks.
59    """
60    mutex = threading.Lock()
61
62    def callback(messages: Sequence[str]) -> None:
63        with mutex:
64            for message in messages:
65                file.write(prefix)
66                file.write(message)
67                file.write("\n")
68            file.flush()
69
70    return callback

Returns a message callback that prints to a file.

It prints its output to the given text file, prefixing each line with the given prefix.

For each call to the returned message callback, the output_stream is flushed.

Arguments:
  • file: The file to print to. It prints to stdout by default.
  • prefix: The prefix to print in front of each line.
Returns:

A function matching the expected signature for message callbacks.

def log_messages(messages: Sequence[str], *, level: int = 0, prefix: str = '') -> None:
73def log_messages(
74    messages: Sequence[str], *, level: int = logging.INFO, prefix: str = ""
75) -> None:
76    """Logs the input messages from a message callback using absl.logging.log().
77
78    It logs each line with the given prefix. It setups absl.logging so that the
79    logs use the file name and line of the caller of this function.
80
81      Typical usage example:
82
83      result = solve.solve(
84          model, parameters.SolverType.GSCIP,
85          msg_cb=lambda msgs: message_callback.log_messages(
86              msgs, prefix='[solver] '))
87
88    Args:
89      messages: The messages received in the message callback (typically a lambda
90        function in the caller code).
91      level: One of absl.logging.(DEBUG|INFO|WARNING|ERROR|FATAL).
92      prefix: The prefix to print in front of each line.
93    """
94    for message in messages:
95        logging.log(level, "%s%s", prefix, message)

Logs the input messages from a message callback using absl.logging.log().

It logs each line with the given prefix. It setups absl.logging so that the logs use the file name and line of the caller of this function.

Typical usage example:

result = solve.solve( model, parameters.SolverType.GSCIP, msg_cb=lambda msgs: message_callback.log_messages( msgs, prefix='[solver] '))

Arguments:
  • messages: The messages received in the message callback (typically a lambda function in the caller code).
  • level: One of absl.logging.(DEBUG|INFO|WARNING|ERROR|FATAL).
  • prefix: The prefix to print in front of each line.
def vlog_messages(messages: Sequence[str], level: int, *, prefix: str = '') -> None:
101def vlog_messages(messages: Sequence[str], level: int, *, prefix: str = "") -> None:
102    """Logs the input messages from a message callback using absl.logging.vlog().
103
104    It logs each line with the given prefix. It setups absl.logging so that the
105    logs use the file name and line of the caller of this function.
106
107      Typical usage example:
108
109      result = solve.solve(
110          model, parameters.SolverType.GSCIP,
111          msg_cb=lambda msgs: message_callback.vlog_messages(
112              msgs, 1, prefix='[solver] '))
113
114    Args:
115      messages: The messages received in the message callback (typically a lambda
116        function in the caller code).
117      level: The verbose log level, e.g. 1, 2...
118      prefix: The prefix to print in front of each line.
119    """
120    for message in messages:
121        logging.vlog(level, "%s%s", prefix, message)

Logs the input messages from a message callback using absl.logging.vlog().

It logs each line with the given prefix. It setups absl.logging so that the logs use the file name and line of the caller of this function.

Typical usage example:

result = solve.solve( model, parameters.SolverType.GSCIP, msg_cb=lambda msgs: message_callback.vlog_messages( msgs, 1, prefix='[solver] '))

Arguments:
  • messages: The messages received in the message callback (typically a lambda function in the caller code).
  • level: The verbose log level, e.g. 1, 2...
  • prefix: The prefix to print in front of each line.
def list_message_callback(sink: List[str]) -> Callable[[Sequence[str]], NoneType]:
127def list_message_callback(sink: List[str]) -> SolveMessageCallback:
128    """Returns a message callback that logs messages to a list.
129
130    Args:
131      sink: The list to append messages to.
132
133    Returns:
134      A function matching the expected signature for message callbacks.
135    """
136    mutex = threading.Lock()
137
138    def callback(messages: Sequence[str]) -> None:
139        with mutex:
140            for message in messages:
141                sink.append(message)
142
143    return callback

Returns a message callback that logs messages to a list.

Arguments:
  • sink: The list to append messages to.
Returns:

A function matching the expected signature for message callbacks.