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