Repository navigation
Feat/login - #1477
Feat/login#1477
Conversation
SAKURA-CAT
commented
Mar 8, 2026
- 将api host、web host等参数重新规划,现在在settings初始化时会尝试加载api host、web host等参数
- 完成swanlab.login命令,删除web_host接口
- 提供了一个上下文接收器 scope,这在一些需要获取底层数据的场景非常好用
Major refactor: extract loading animation to swanlab.sdk.pkg.helper.rich, add a Scope context manager, and restructure client and settings. Key changes: - Introduced internal/pkg/scope.py (Scope context manager) and exported Scope/get_context/set_context via internal/pkg.__init__. - Moved with_loading_animation into swanlab.sdk.pkg.helper.rich and exposed it via swanlab.sdk.pkg.helper. - Refactored core_python.client API: added new/exists/reset/_get_client, added timeout handling, store login response into Scope via set_context, and simplified global proxy helpers. - Moved strip_none into internal.settings, added a pre-validator to clean empty values, and introduced an interactive setting flag. - Updated apikey and console imports to use internal.pkg helpers. - Reworked login flow to use Scope, prompt/save API keys, and create client with loading animation. - Updated and added unit tests to cover Scope, settings.strip_none, and the updated client lifecycle and behaviors.
Refactor login flow and API key prompting: login.py now returns early if already logged in, defaults host from current settings, and annotates the login steps with clearer comments. The interactive-mode check for missing API keys was moved from login.py into internal/apikey.prompt(), which now raises a RuntimeError when interactive mode is disabled (and documents terminal password limitations). This centralizes responsibility for interactive prompting and simplifies the login logic.
Move netrc read/write helpers into swanlab.sdk.internal.pkg.netrc and centralize netrc operations (get_nrc_path, read_netrc_by_host, write_netrc, remove_host_suffix). Update apikey module to use the new netrc utilities and sync API key into Settings; simplify get/exists to rely on current Settings. Add use_temp_context/RunConfig in internal.context and update swanlab.sdk.cmd.login to run login inside a temporary RunContext, prevent relogin when a global context is active, and export login from package init files. Add a Settings model validator to load .netrc as a fallback for unset fields and tighten console import path. Update and add unit tests to cover netrc utilities, Settings netrc fallback, and apikey flows; minor test fixture adjustments and renames for scope/settings modules.
Import remove_host_suffix and use it to ensure the client's base_url consistently ends with a single "/api" (avoids duplicate suffixes when composing URLs). Also return the full login response from login_by_api_key instead of None so callers can access returned metadata (e.g. expiredAt). No behavioral changes to session handling.
Add web_host to the temporary login Settings and default it from existing settings. The change updates Settings.model_validate to include "web_host" (derived from host or settings.web_host) and uses web_host when saving the API key instead of using the username from the login response. This ensures credentials are saved/scoped by the web host.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 此拉取请求旨在通过引入 Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This Pull Request significantly refactors configuration processing and authentication workflows. Key changes include implementing the swanlab.login command, centralizing configuration management within the Settings class with .netrc support, and introducing a Scope context manager for clean data passing. While these changes improve code quality and maintainability, a critical security vulnerability has been identified: the current implementation for saving credentials to the .netrc file is susceptible to Netrc Injection. This is due to a lack of validation or escaping of newlines in API key or host parameters, which could allow an attacker to inject malicious entries into the shared configuration file. It is strongly recommended to add validation to prevent newlines or control characters in usernames and passwords. Additionally, the code review identified a minor bug and an area for improvement, which are detailed in the specific comments.
Update settings package docs to include settings.root in the config load priority and renumber items accordingly. Refactor client unit tests: rename mock_url -> mock_base_url, add mock_api_url fixture (base + "/api"), update client fixture to use mock_base_url, and change assertions/response stubs to expect the client to force-append "/api" to base URLs. Also refine token refresh and global proxy tests and adjust responses URLs to use the composed mock_api_url.
Pass web_host into Settings.model_validate during login so the client is created with the correct web host. Also broaden netrc parsing error handling to include PermissionError (to accommodate Windows permission/dir-as-file cases) and improve the netrc access/parse error message.
Add input validation for host, username, and password when writing the netrc file. The code now rejects values containing newlines, carriage returns, spaces, or tabs and raises ValueError, preventing malformed .netrc entries or injection via credential fields. Existing path conflict check (raising IOError if the target is a directory) remains unchanged.
Rename Makefile test target to `unit` (runs tests/unit) and add comprehensive test isolation and login tests. Update tests/unit/conftest.py to provide an autouse fixture that isolates file-system/env (SWANLAB_SAVE_DIR), resets the Settings singleton (including Pydantic internal state), clears the global client and RunContext. Add tests/unit/sdk/cmd/test_login.py with E2E-style tests for login behavior (skip when already logged in, blocked when context active, successful login flows with explicit/prompted keys, custom hosts/relogin, and network failure handling) using responses and monkeypatch to stub network and env. These changes ensure unit tests run in a hermetic environment and avoid cross-test leakage.
Rename and centralize exceptions to swanlab.exceptions and add AuthenticationError. Update login flow to use the new AuthenticationError, fix api_host variable handling, and raise on missing login response. Improve API key prompt: add secure getpass input, interactive-environment checks, richer console guidance, Windows paste hint, and graceful interrupt handling; introduce swanlab.sdk.pkg.helper.env.is_interactive. Add a console.print wrapper to gate plain prints. Make client._refresh_auth optionally silent (warning flag) and adjust session imports to use swanlab.exceptions.ApiError. Update helper exports and unit tests to reflect these changes.
Expand and clarify documentation for swanlab.sdk.cmd.login and swanlab.sdk.cmd.merge_settings: add usage examples, reformat and clarify parameter descriptions (api_key, relogin, host, save, timeout), and make the raised exceptions more explicit. merge_settings docstring now includes an Examples section. These are documentation-only edits to improve developer UX; no functional logic changes were made.
Normalize and validate host input in login(): strip whitespace/trailing slashes, add https:// if missing, and remove path/query by using urllib.parse.urlparse. Prevent relogin while a RunContext is active and call client.reset() when relogin=True and a client exists. Protect the official api.swanlab.cn case so passing an api host does not overwrite the default web_host. Add a global declaration in client.exists() to avoid local/global issues. Update and add unit tests to cover host cleaning and official-host protection, and adjust existing tests to patch client.reset().
Remove the debug field from Settings and decouple the console logger from settings. The console module now determines debug mode from the SWANLAB_DEBUG environment variable and no longer imports settings.get_current_settings. Settings imports the console to emit a warning when .netrc loading fails instead of silently passing. Update unit test to stop asserting settings.debug and adjust expectations accordingly. These changes reduce cross-module coupling and centralize debug control via an environment variable.