This repository was archived by the owner on Feb 24, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 86
PR #362 Review #440
Closed
Closed
PR #362 Review #440
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # PR #362 Review: google-auth-library-python-oauthlib | ||
|
|
||
| **PR Link**: https://github.com/googleapis/google-auth-library-python-oauthlib/pull/362/ | ||
| **Reviewer**: Jules (Senior Staff Software Engineer) | ||
|
|
||
| ## 1. Conflict & Relevance Check | ||
| - **Conflicts**: None. The changes apply cleanly to the current codebase. | ||
| - **Relevance**: The PR addresses a valid use case: running the library in headless environments where standard output (print) might not be captured, but logging is. This aligns with improving observability. | ||
|
|
||
| ## 2. Functional Correctness | ||
| - **Logic**: The implementation adds a log statement alongside the existing print statement. This correctly duplicates the output to the logger. | ||
| - **Edge Cases**: | ||
| - The `authorization_prompt_message` is formatted before logging. This relies on the message string (which can be user-provided) accepting the `url` keyword argument. This matches existing behavior for the `print` statement, so it introduces no new risks regarding formatting. | ||
| - The use of `_LOGGER.setLevel(logging.INFO)` effectively hardcodes the logger level to INFO for this module. This is the main functional issue (see Critical Issues). | ||
|
|
||
| ## 3. Thoroughness | ||
| - **Scope**: The change is applied to `run_local_server` in `google_auth_oauthlib/flow.py`. This is the primary interactive entry point, so the scope is appropriate. | ||
| - **Missing Instances**: No other obvious places need similar changes for this specific feature request. | ||
|
|
||
| ## 4. Google Python Standards | ||
| - **Logging**: | ||
| - **Violation**: The PR sets the logger level within the library code: `_LOGGER.setLevel(logging.INFO)`. | ||
| - **Why it's bad**: Libraries should never manually configure logging handlers or levels. This overrides the application developer's configuration. If an application developer sets the root logger to `WARNING`, this library will force its own logs to be processed at `INFO` level (though they might still be filtered by handlers), or worse, if the application relies on inheritance, this interferes with hierarchy. | ||
| - **Correct Approach**: The library should emit logs at the appropriate level (`INFO`), and let the application developer decide whether to see them by configuring the logging system (e.g., `logging.getLogger("google_auth_oauthlib").setLevel(logging.INFO)`). | ||
|
|
||
| ## 5. Technical Merit & Architecture | ||
| - **Approach**: Adding logging is the correct way to solve the visibility issue in headless environments. | ||
| - **Implementation**: Over-engineered by trying to force the log level. A simpler, idiomatic Python solution is to just emit the log and assume the user will configure logging if they care about it. | ||
|
|
||
| ## 6. Testing | ||
| - **Status**: **Insufficient**. The PR does not include any tests. | ||
| - **Requirement**: A test case should be added to `tests/unit/test_flow.py` to verify that `run_local_server` emits the expected log message. | ||
|
|
||
| ## 7. Critical Issues | ||
| - **Blocker**: `_LOGGER.setLevel(logging.INFO)` must be removed. It violates Python logging best practices and Google Python style for libraries. | ||
| - **Breaking Changes**: No breaking API changes, but the logging behavior change is intrusive. | ||
|
|
||
| ## 8. Suggested Refactors | ||
|
|
||
| ### Remove explicit level setting | ||
| Remove the line that sets the level. | ||
|
|
||
| ```python | ||
| <<<<<<< SEARCH | ||
| _LOGGER = logging.getLogger(__name__) | ||
| _LOGGER.setLevel(logging.INFO) | ||
| ======= | ||
| _LOGGER = logging.getLogger(__name__) | ||
| >>>>>>> REPLACE | ||
| ``` | ||
|
|
||
| ### Add Test Case | ||
| Add a test case to `tests/unit/test_flow.py` to verify logging. | ||
|
|
||
| ```python | ||
| @mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True) | ||
| def test_run_local_server_logs_url(self, webbrowser_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 instance.redirect_uri in caplog.text | ||
|
Comment on lines
+56
to
+78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a great test case suggestion for verifying the new logging behavior. To make it even more robust and ensure no existing functionality is broken, consider also asserting that the original @mock.patch("builtins.print")
@mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True)
def test_run_local_server_logs_and_prints_url(self, print_mock, webbrowser_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 instance.redirect_uri in caplog.text
# Verify print message
print_mock.assert_called_once()
assert "Please visit this URL" in print_mock.call_args[0][0]
assert instance.redirect_uri in print_mock.call_args[0][0] |
||
| ``` | ||
| *(Note: `caplog` is a pytest fixture. If using `unittest`, `assertLogs` would be used.)* | ||
|
|
||
| ## Verdict | ||
| **Needs Revision** | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of
<<<<<<< SEARCHand>>>>>>> REPLACEis a bit unconventional for presenting code changes in a review document. For better readability and to adhere to a more standard format, consider using adiffcode block. This makes it immediately clear what lines are being removed or added.