- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
导读
本文以 lakeFS 官方 Python SDK(lakefs_sdk)中的User数据模型为核心,完整解析该模型的id、creation_date、friendly_name、email四个字段的定义、约束与适用场景,并通过from_json/to_json/to_dict/from_dict等完整示例展示 JSON 与 Python 对象的互转方式。同时结合 api/swagger.yml 中/auth/users系列 REST 接口、SDK 中的 auth_api.py 实现以及服务端 pkg/auth/basic_service.go 的底层逻辑,带你掌握"模型字段 + API 调用 + 用户生命周期管理"的完整链路,能够在 Python 项目中直接落地用户创建、查询、列出与删除。
User 模型字段全解析
User模型在 SDK 中定义于 clients/python/lakefs_sdk/models/user.py,由 OpenAPI Generator 依据 api/swagger.yml 中的Userschema(见 api/swagger.yml#L900-L923)自动生成。其类型定义如下:
class User(BaseModel): id: StrictStr = Field(..., description="A unique identifier for the user. Cannot be edited.") creation_date: StrictInt = Field(..., description="Unix Epoch in seconds") friendly_name: Optional[StrictStr] = Field(None, description="A shorter name for the user than the id. Unlike id it does not identify the user (it might not be unique). Used in some places in the UI. ") email: Optional[StrictStr] = Field(None, description="The email address of the user. If API authentication is enabled, this field is mandatory and will be invited to login. If API authentication is disabled, this field will be ignored. All current APIAuthenticators require the email to be lowercase and unique, although custom authenticators may not enforce this. ")四个字段的完整语义对照如下:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | str | 是 | 用户的唯一标识符(Unique identifier),创建后不可修改(Cannot be edited)。 |
| creation_date | int | 是 | 用户创建时间,以Unix Epoch 秒为单位(Unix Epoch in seconds)。 |
| friendly_name | str | 否 | 比id更短的用户显示名。与id不同,它不唯一、不能用于身份识别,仅用于 UI 等展示场景。 |
str | 否 | 用户邮箱地址。启用 API 认证时该字段为必填,且会被邀请登录;禁用 API 认证时该字段被忽略。当前所有 APIAuthenticators 都要求邮箱小写且唯一(自定义 authenticator 可能不强制)。 |
服务端的字段映射
User模型并非 SDK 独有,服务端 pkg/auth/model/model.go 中存在对应的领域模型User(见 pkg/auth/model/model.go#L101-L114):
type User struct { CreatedAt time.Time `db:"created_at"` // Username is a unique identifier for the user. In password-based authentication, it is the email. Username string `db:"display_name" json:"display_name"` // FriendlyName, if set, is a shorter name for the user than // Username. Unlike Username, it does not identify the user (it // might not be unique); use it in the user's GUI rather than in // backend code. FriendlyName *string `db:"friendly_name" json:"friendly_name"` Email *string `db:"email" json:"email"` EncryptedPassword []byte `db:"encrypted_password" json:"encrypted_password"` Source string `db:"source" json:"source"` ExternalID *string `db:"external_id" json:"external_id"` }从服务端源码可以确认几个关键事实:
- 服务端的
Username即对外暴露的id字段,它是认证体系中的唯一标识;在基于密码的认证模式下,用户名就是邮箱(源码注释原文:"In password-based authentication, it is the email"),这解释了为什么启用 API 认证时email会变成必填。 - 服务端
FriendlyName的注释与服务端db标签均指向friendly_name列,明确说明其仅供 GUI 展示、不参与身份识别,与 SDK 文档语义完全一致。 - SDK 文档中的
creation_date(Unix 秒)在服务端表现为CreatedAt time.Time,是同一个字段在不同 API 层的时间表示形式。
id 的校验规则
创建用户时传入的id会经过服务端校验,规则见 pkg/auth/model/validation.go 中的ValidateAuthEntityID:
func ValidateAuthEntityID(name string) error { if len(name) == 0 { return fmt.Errorf("empty name: %w", ErrValidationError) } if strings.Contains(name, kv.PathDelimiter) { return fmt.Errorf("name contains delimiter %s: %w", kv.PathDelimiter, ErrValidationError) } return nil }即:id不能为空,且不能包含路径分隔符(kv.PathDelimiter)。这在 pkg/auth/basic_service.go 的CreateUser中被首先调用(见 pkg/auth/basic_service.go#L174-L176),不满足校验时直接返回InvalidUserID与校验错误。
User 对象与 JSON 的序列化互转
User继承自 pydantic 的BaseModel,其Config中开启了allow_population_by_field_name = True与validate_assignment = True,因此既可以通过字段名构造,也可以在赋值时触发类型校验。模型内置了四个序列化方法(实现见 clients/python/lakefs_sdk/models/user.py):
| 方法 | 作用 |
|---|---|
to_str() | 返回带别名的字符串表示(pprint.pformat) |
to_json() | 返回 JSON 字符串(json.dumps) |
to_dict() | 返回字典(by_alias=True,且exclude_none=True,即 None 字段会被剔除) |
from_json(json_str) | 从 JSON 字符串反序列化出User实例 |
from_dict(obj) | 从字典构造User实例 |
从 JSON 字符串创建 User
from lakefs_sdk.models.user import User # 一个真实的用户 JSON(假设来自 /auth/users 接口响应) json = '{"id": "jane.doe", "creation_date": 1690000000, "friendly_name": "Jane", "email": "jane.doe@example.com"}' # create an instance of User from a JSON string user_instance = User.from_json(json) # 访问字段 print(user_instance.id) # jane.doe print(user_instance.creation_date) # 1690000000 print(user_instance.friendly_name) # Jane print(user_instance.email) # jane.doe@example.com注意:from_json内部实现为cls.from_dict(json.loads(json_str)),因此 JSON 中缺失的字段(如friendly_name、email)会解析为None,而非报错;但id与creation_date是必填字段,缺失时 pydantic 会抛出校验异常。
输出 JSON 字符串与字典
# print the JSON string representation of the object print(user_instance.to_json()) # 输出: {"id": "jane.doe", "creation_date": 1690000000, "friendly_name": "Jane", "email": "jane.doe@example.com"} # convert the object into a dict user_dict = user_instance.to_dict() print(user_dict) # {'id': 'jane.doe', 'creation_date': 1690000000, 'friendly_name': 'Jane', 'email': 'jane.doe@example.com'} # create an instance of User from a dict user_from_dict = User.from_dict(user_dict)由于to_dict()采用exclude_none=True,当一个字段未被设置时它不会出现在字典中:
partial_user = User(id="alice", creation_date=1690000000) print(partial_user.to_dict()) # {'id': 'alice', 'creation_date': 1690000000} # friendly_name / email 为 None 被剔除这个特性在实际对接 REST API 时非常实用:未设置的可选字段不会以null形式出现在请求或响应体中,避免多余的null字段。
通过 SDK 管理用户(Auth API 实战)
User模型在 SDK 中主要作为 auth_api.py 的入参与返回值出现。该 API 对应 api/swagger.yml 中tags: [auth]的/auth/users系列端点。以下四个方法覆盖了用户生命周期的完整闭环。
创建用户:create_user
创建用户时,需要先构造UserCreation模型(定义于 clients/python/lakefs_sdk/models/user_creation.py),它只有一个必填字段id:
from lakefs_sdk.api.auth_api import AuthApi from lakefs_sdk.models.user_creation import UserCreation from lakefs_sdk import Configuration, ApiClient configuration = Configuration(host="http://localhost:8000") configuration.access_token = "your_access_token" client = ApiClient(configuration) auth_api = AuthApi(client) user_creation = UserCreation(id="jane.doe") # 创建用户,成功返回 201 及 User 对象 created_user = auth_api.create_user(user_creation=user_creation) print(created_user.id) print(created_user.creation_date) # Unix 秒时间戳对应 REST 为POST /auth/users(见 api/swagger.yml#L2234-L2264),服务端在 pkg/auth/basic_service.go 的CreateUser中执行model.ValidateAuthEntityID校验,并使用kv.SetMsgIf(CAS 语义)写入用户数据——若用户已存在,返回409 Conflict,对应 swagger 中定义的Conflict响应。
查询单个用户:get_user
user = auth_api.get_user(user_id="jane.doe") print(user.id) print(user.creation_date) print(user.friendly_name) print(user.email)对应 REST 为GET /auth/users/{userId}(见 api/swagger.yml#L2273-L2294),用户不存在时返回404 NotFound。在服务端,GetUser会先校验请求者权限,再通过缓存与 KV 存储定位用户记录(见 pkg/auth/basic_service.go#L143-L153)。
分页列出用户:list_users
list_users支持三个分页参数(见 clients/python/lakefs_sdk/api/auth_api.py#L4696-L4726):
users_page = auth_api.list_users( prefix="jane", # 返回以该值开头的条目,可选 after=None, # 返回该值之后的条目,可选 amount=100, # 返回条数,可选,范围 -1 ~ 1000 ) for user in users_page.results: print(user.id, user.creation_date, user.friendly_name, user.email) # 分页信息 print(users_page.pagination.has_more) print(users_page.pagination.next_offset)返回类型为UserList(定义于 clients/python/lakefs_sdk/models/user_list.py),包含results(User[])与pagination两个必填字段,对应 api/swagger.yml#L1115-L1126 的UserListschema。三个参数的行为如下:
prefix:只返回 id 以该值开头的用户;after:从指定用户之后继续分页(用于翻页);amount:单页条数,合法范围-1到1000。
删除用户:delete_user
# 成功时返回 None(HTTP 204) auth_api.delete_user(user_id="jane.doe")对应 REST 为DELETE /auth/users/{userId}(见 api/swagger.yml#L2295-L2304)。服务端的DeleteUser除了删除用户记录外,还会级联清理该用户的凭证(credentials),见 pkg/auth/basic_service.go#L190-L203 中的deleteUserCredentials调用,因此在删除用户后其关联的 Access Key 也随之失效。
获取当前登录用户:get_current_user
current = auth_api.get_current_user() print(current.user.id)对应 REST 为GET /auth/user(见 api/swagger.yml#L2100-L2111),返回CurrentUser对象(见 api/swagger.yml#L925-L931),其唯一的user字段类型正是User。
与 lakectl 命令行的对照
User模型的字段在 lakectl 的用户管理命令中也有直接体现,便于交叉验证:
- cmd/lakectl/cmd/auth_users_create.go:
lakectl auth users create --id <username>,内部调用CreateUserWithResponse,成功后展示ID与Creation Date; - cmd/lakectl/cmd/auth_users_list.go:
lakectl auth users list,内部读取每个用户的CreationDate、FriendlyName、Email、Id字段并渲染成表格。其展示逻辑值得注意:
username := cmdutils.Coalesce(user.FriendlyName, user.Email, user.Id)即在表格的 "User" 列中,优先显示friendly_name,其次email,兜底才用id。这恰好印证了模型文档中"friendly_name用于 UI 展示"的设计意图。
使用建议与注意事项
id一经创建不可修改:设计用户体系时,应把id当作稳定的业务主键对待;如需要展示名,请使用friendly_name。email与认证模式强相关:启用 API 认证时email必填且会被邀请登录;关闭 API 认证时email会被忽略。同时当前内置认证器要求邮箱小写且唯一,写入前建议做lower()归一化。- 时间戳语义:
creation_date是 Unix Epoch 秒(int64),在 Python 中可用datetime.fromtimestamp(user.creation_date)转换为人可读时间;lakectl 中也同样用time.Unix(user.CreationDate, 0)处理(见 cmd/lakectl/cmd/auth_users_list.go#L34)。 - 删除是级联的:
delete_user会同时清理用户凭证,属于不可逆操作,生产环境需谨慎。
延伸阅读
- 模型定义:clients/python/lakefs_sdk/models/user.py、clients/python/lakefs_sdk/models/user_creation.py、clients/python/lakefs_sdk/models/user_list.py
- API 客户端:clients/python/lakefs_sdk/api/auth_api.py
- OpenAPI 规范:api/swagger.yml(
Userschema 见 api/swagger.yml#L900-L923,/auth/users端点见 api/swagger.yml#L2209-L2304) - 服务端实现:pkg/auth/basic_service.go、pkg/auth/model/model.go、pkg/auth/model/validation.go
- CLI 对照:cmd/lakectl/cmd/auth_users_create.go、cmd/lakectl/cmd/auth_users_list.go
- SDK 总览:clients/python/README.md
- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
相关推荐
lakeFS Rust SDK 中 User 模型详解:字段语义、serde 序列化与认证 API 实战
lakeFS Rust SDK 中 User 模型详解:字段语义、serde 序列化与认证 API 实战 lakeFS 的 Rust 客户端( lakefs_s
数据工程数据湖大数据对象存储后端想要免费的气象数据?Open-Meteo 完整接入与自托管指南
想要免费的气象数据?Open Meteo 完整接入与自托管指南 Open Meteo 是一个开源的免费天气API。不用注册,不要API Key,一条命令就能拿到
数据工程数据湖大数据对象存储后端lakeFS Python SDK 中 Group 模型的字段、序列化与认证 API 使用指南
lakeFS Python SDK 中 Group 模型的字段、序列化与认证 API 使用指南 导读 Group 是 lakeFS Python SDK( la
数据工程数据湖大数据对象存储后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考