From 810008e9cdc65c5376e86145bf76c82ae4e83cea Mon Sep 17 00:00:00 2001 From: Matt Black Date: Sun, 7 Jul 2024 16:10:05 +1000 Subject: [PATCH 1/4] feat: Log the flow.run_local_server redirect URL --- google_auth_oauthlib/flow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index e564ca4..652c04c 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -69,6 +69,7 @@ _LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) class Flow(object): @@ -447,6 +448,7 @@ def run_local_server( webbrowser.get(browser).open(auth_url, new=1, autoraise=True) if authorization_prompt_message: + _LOGGER.info(authorization_prompt_message.format(url=auth_url)) print(authorization_prompt_message.format(url=auth_url)) local_server.timeout = timeout_seconds From df70911349c2a92dc970304c972269e40eca5472 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 6 Feb 2026 15:26:25 -0500 Subject: [PATCH 2/4] adds unittest to PR --- tests/unit/test_flow.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/unit/test_flow.py b/tests/unit/test_flow.py index 84ae953..ee4b37a 100644 --- a/tests/unit/test_flow.py +++ b/tests/unit/test_flow.py @@ -16,6 +16,7 @@ import datetime from functools import partial import json +import logging import os import re import socket @@ -460,3 +461,35 @@ def test_local_server_socket_cleanup( instance.run_local_server() server_mock.server_close.assert_called_once() + + @mock.patch("builtins.print") + @mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True) + def test_run_local_server_logs_and_prints_url( + self, webbrowser_mock, print_mock, instance, mock_fetch_token, port, caplog + ): + auth_redirect_url = urllib.parse.urljoin( + f"http://localhost:{port}", self.REDIRECT_REQUEST_PATH + ) + + # Configure caplog to capture INFO logs + caplog.set_level(logging.INFO, logger="google_auth_oauthlib.flow") + + with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool: + future = pool.submit(partial(instance.run_local_server, port=port)) + + while not future.done(): + try: + requests.get(auth_redirect_url) + except requests.ConnectionError: + pass + + future.result() + + # Verify log message + assert "Please visit this URL" in caplog.text + assert urllib.parse.quote(instance.redirect_uri, safe="") in caplog.text + + # Verify print message + print_mock.assert_called_once() + assert "Please visit this URL" in print_mock.call_args[0][0] + assert urllib.parse.quote(instance.redirect_uri, safe="") in print_mock.call_args[0][0] From 26f5bc3bd074ecfadd548d49ff3f38f8be2c6034 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Fri, 6 Feb 2026 15:30:46 -0500 Subject: [PATCH 3/4] Apply suggestion from @chalmerlowe Remove unnecessary logger.setlevel command. --- google_auth_oauthlib/flow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index 33f8d51..9c52711 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -69,7 +69,6 @@ _LOGGER = logging.getLogger(__name__) -_LOGGER.setLevel(logging.INFO) class Flow(object): From 7aed4b2e4cfaa352a44f9d23f1e199ce4bbe3c91 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Mon, 9 Feb 2026 10:21:23 -0500 Subject: [PATCH 4/4] updates linting --- tests/unit/test_flow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_flow.py b/tests/unit/test_flow.py index ee4b37a..d9833fe 100644 --- a/tests/unit/test_flow.py +++ b/tests/unit/test_flow.py @@ -492,4 +492,7 @@ def test_run_local_server_logs_and_prints_url( # Verify print message print_mock.assert_called_once() assert "Please visit this URL" in print_mock.call_args[0][0] - assert urllib.parse.quote(instance.redirect_uri, safe="") in print_mock.call_args[0][0] + assert ( + urllib.parse.quote(instance.redirect_uri, safe="") + in print_mock.call_args[0][0] + )