Skip to content

Comments

feat: get all user when login as root user#1438

Merged
SAKURA-CAT merged 5 commits intofeature/open-apifrom
feat/list-user
Feb 3, 2026
Merged

feat: get all user when login as root user#1438
SAKURA-CAT merged 5 commits intofeature/open-apifrom
feat/list-user

Conversation

@Bainianzzz
Copy link
Collaborator

@Bainianzzz Bainianzzz commented Feb 2, 2026

Description

  • 超级管理员可以获取所有用户
  • 优化装饰器的身份校验

example code:

import swanlab

if __name__ == '__main__':
    api = swanlab.Api()
    all_users = api.users()
    for user in all_users:
        print(user.json())

- opt @self_hosted decorator identity checking
- add api func get_users()
@Bainianzzz Bainianzzz self-assigned this Feb 2, 2026
@Bainianzzz Bainianzzz added 💪 enhancement New feature or request 🔌 api SwanLab OpenAPI labels Feb 2, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Bainianzzz, 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!

此拉取请求主要实现了超级管理员获取所有用户列表的功能,并通过引入新的API端点和客户端方法来支持这一操作。同时,对现有的身份校验装饰器进行了增强,以提高安全性,确保只有经过认证的根用户才能执行敏感操作。

Highlights

  • 新增超级管理员获取所有用户功能: 为超级管理员引入了 list_user 方法,允许其分页获取系统中的所有用户。
  • 优化身份校验装饰器: @self_hosted("root") 装饰器增加了额外的校验逻辑,确保只有已认证的根用户实例才能执行特定操作。
  • 新增后端用户列表API: 在 swanlab/core_python/api/user/self_hosted.py 中添加了 get_users 函数,用于调用 /self_hosted/users 接口获取用户列表。

🧠 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.

Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new feature allowing a root user to retrieve a list of all users. It also includes a refactoring of the @self_hosted decorator to centralize permission checks. The implementation of the user listing is sound, using pagination to handle potentially large numbers of users.

My review focuses on improving the clarity, maintainability, and correctness of the new code. I've pointed out a misleading docstring and a hardcoded value in the new list_user method. More importantly, I've identified a potential logic issue in the updated @self_hosted decorator that could lead to unintended behavior. Finally, I've suggested adding a docstring to the new get_users helper function for better documentation.

- opt identity checking logic
@Bainianzzz Bainianzzz requested a review from SAKURA-CAT February 2, 2026 06:02
Replaced the users() method in Api to return a new Users iterator class instead of yielding User objects directly. Added swanlab/api/users/__init__.py to encapsulate user iteration logic, improving code organization and separation of concerns.
Added a test for paginated user retrieval in test_user.py and implemented create_user_data in utils.py to simulate paginated user data. Also clarified the docstring in create_user for self-hosted admin restriction.
@SAKURA-CAT SAKURA-CAT merged commit bdfca37 into feature/open-api Feb 3, 2026
5 checks passed
@SAKURA-CAT SAKURA-CAT deleted the feat/list-user branch February 3, 2026 06:42
Zeyi-Lin added a commit that referenced this pull request Feb 3, 2026
* feat(init): api login (#1380)

* feat: get all projects through OpenApi (#1382)

* feat: get all project of a group

* update unit test using magicMock

* update unit test & fix bug

* opt import and rename some file

- move api from folder core_python to api

* fix wrong comment

* remove pending status when getting entity projects

* opt Project class

- add EN comment for Project properties
- add __str__ method for project label
- adapt snake_case naming for project properties
- change some project property name: projectLabels -> label
- change api.projects() param name: entity -> workspace
- delete some project properties (group, cuid)
- prase url inside Project class

* dynamically request project data according to the traversal of the project, rather than requesting all project information at once

* opt import

* iteratively request project data inside the Projects class

- move api form api package to core_python package

* fix bug & add type

* move api's type.py to core_python

* Feat/api runs user (#1403)

* feat: get runs metadata

- add api in core_python to get all exps in a project
- add new type and class to parse exps

* update unit test & fix bugs

* opt code style & add comment

* raise value error if user's path is invaded

* fix bug of Incorrectly raised ValueError

* get single exp through OpenApi

* resolve conflicts: filtering exp (basic implement)

- get full single exp info through filter func

# Conflicts:
#	swanlab/core_python/api/experiment.py

* opt __dict__ for project and experiment

* resolve conflict: update run.history()

* feat: update run.scan_history()

- add example codes

* resolve conflict: fix bugs when importing pandas

* import pandas only when used

* fix: pandas warning

* feat: run and user features of OpenApi

- get metric data in batch
- recover old OpenApi version for smooth transition
- create & delete api_key through Api.user

* opt Client importing in core_python's api

* opt logic of run.history()

- get latest api_keys when user delete api_key

* rename the deprecated openApi folder

* refactored run.history() & add return type

- add return type for the backend interfaces
- simplified get_experiment_metrics() and handle the csv inside HistoryPool

* removed redundant types

* update unit test using mock

* feat: get user's team

* feat: create user if user is the root user in self-hosted swanlab

- refactor the models in OpenApi

* feat: update unit test for create user and get user teams

* delete test code of OpenApi

* use ThreadPoolExecutor in HistoryPool

* Refactor Api class and cleanup api module structure

Moved the Api class implementation from swanlab/api/api.py to swanlab/api/__init__.py and deleted the redundant api.py file. Updated imports and references accordingly. Minor docstring and comment improvements, and fixed a message in thread.py to reference 'Api' instead of 'OpenApi'.

* Fix circular import by updating Api export

Combined the import of OpenApi and Api from .api to prevent circular import issues and simplify the export process.

---------

Co-authored-by: ZeYi Lin <944270057@qq.com>
Co-authored-by: Kang Li <cunykang@gmail.com>

* refactor open api (#1411)

* Refactor the OpenAPI codes, managing the code with a modular approach

* combine 3 kinds of user into one

- use @cached_property to cache some property of user

* Place the API's custom type into a separate module

- place class ApiBase into a single model

* get the user identity at the init of the OpenApi

- only the root user get by api.user() can create new account

* refactor module name & structure in api and core_python

* Modified parameter passing convention & add client property to ApiBase

- pass param through kwargs except client in OpenApi and core_python

* update code commit

- opt str() of Label class

* feat: open api unit tests (#1420)

* add unit test

- add unit test and fix bugs of getting all projects through OpenApi
- add unit tests for OpenApi runs and run.history()

* add unit test for api.user()

* accept suggestions from gemini

* fix bugs in projects

* revert changes

* Opt open api code (#1424)

* delete class ApiBase

* accept suggestions

- place yield inside the loop of the projects
- check if creating & deleting user or api_keys inside the api func
- add property is_self in user

* opt user api func

* fix bugs in projects

* accept gemini suggestions

- fix type error in self_hosted.py and user's api func
- add a constant for project page size

* opt over-encapsulated code

- discard constant PAGE_SIZE
- let adapter handle the exception when creating & deleting user info
- opt unit test for projects

* delete unused utils

* resolve conflict

* check self hosted info using a wrapper instead of checking when init (#1425)

* use a wrapper to check self_hosted info for some functions

- update unit tests for user (add self_hosted context)

* fix bug in OpenApi.list_workspaces()

* accept gemini suggestions

* raise value error when not being self_hosted

* raise value error when self_hosted is not available

- raise error when accessing unsupported user functions

* feat: workspace and json() (#1428)

* feat: replace the workspace field in the project object with a workspace object (#1430)

* Replace the workspace field in the project object with a workspace object

* cached the workspace object

* fix: fix bugs when getting info when 'profile' param is None (#1440)

* fix bugs when getting exp info when profile is None

- use getattr() to get profile and related info

* accept gemini suggestions

* feat: get all user when login as root user (#1438)

* get all user when login as root user

- opt @self_hosted decorator identity checking
- add api func get_users()

* accept gemini suggestions

* move get all users function from user to api

- opt identity checking logic

* Refactor user listing to use Users iterator class

Replaced the users() method in Api to return a new Users iterator class instead of yielding User objects directly. Added swanlab/api/users/__init__.py to encapsulate user iteration logic, improving code organization and separation of concerns.

* Add user pagination test and utility function

Added a test for paginated user retrieval in test_user.py and implemented create_user_data in utils.py to simulate paginated user data. Also clarified the docstring in create_user for self-hosted admin restriction.

---------

Co-authored-by: Kang Li <cunykang@gmail.com>

* feat: get single project through openApi (#1439)

* get single project through openApi

- add api func get_project_info

* accept gemini suggestions

* Refactor workspace and project param names to 'path'

Replaces 'workspace' parameters with 'path' across API, core_python, and test modules for consistency. Updates related function calls, class initializations, and docstrings to reflect the new naming convention.

* Refactor Workspace initialization and usage

Updated Workspace class to require client and data parameters, removing path-based initialization logic. Refactored related API, Project, and Workspaces classes to fetch workspace data before instantiating Workspace, ensuring consistent and explicit data handling.

---------

Co-authored-by: Kang Li <cunykang@gmail.com>

* Inline experiment history CSV fetch; remove pool

Remove the threaded HistoryPool helper and simplify Experiment.history by fetching per-key CSVs inline. Deleted swanlab/api/experiment/thread.py and removed its import. The history method now normalizes keys (allowing a single string), appends x_axis, deduplicates, retrieves CSV URLs via the client, reads them with pandas, strips a common prefix and trailing "_step" from column names, and concatenates DataFrames (inner join when x_axis is present, outer otherwise). When x_axis is given, timestamp columns are dropped, the x_axis column is validated and moved to the front. The method now raises if keys is None and supports sample trimming. Note: concurrency via HistoryPool is removed and the pandas parameter is effectively unused (the method returns a pandas DataFrame).

* Rename history() to metrics() in Experiment

Remove Experiment.config and Experiment.summary properties and rename the Experiment.history(...) method to Experiment.metrics(...). Update docstrings, example usage and the pandas import error message to reference metrics. This is an API change — update callers to use exp.metrics(...) and note that config/summary accessors were removed.

* Refactor DataFrame joining and x_axis handling

Introduce x_axis_state to centralize x_axis checks and only append x_axis to keys when applicable. Replace pd.concat(join_type) with iterative outer .join(...).sort_index() to build the result DataFrame, and keep timestamp columns dropped as before. After reordering columns to put x_axis first, filter out rows where x_axis is NaN. Minor cleanup and readability improvements.

* fix test

* fix test

* Improve Experiment.metrics CSV parsing, validation

Refactor Experiment.metrics: tighten keys validation (keys must be a non-empty list of strings), simplify docstring and pandas import error message, and treat pandas param as reserved. Normalize x_axis handling (default 'step'), append x_axis when needed, and fetch each metric CSV. Extract common prefix from the first column, strip that prefix and the "_step" suffix in a Python 3.8-compatible way, then outer-join and sort the DataFrames. When x_axis is used, drop timestamp columns, ensure x_axis exists, move it to the first column and drop rows with null x_axis. Finally apply the optional sample limit.

---------

Co-authored-by: Bainianzzz <95992848+Bainianzzz@users.noreply.github.com>
Co-authored-by: ZeYi Lin <944270057@qq.com>
Co-authored-by: Bainianzzz <3036349123@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔌 api SwanLab OpenAPI 💪 enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants