141 lines
4.7 KiB
Python
141 lines
4.7 KiB
Python
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
|
|
# 保留供其他地方使用
|
|
def _empty_to_null(value):
|
|
"""将空字符串转为 None,避免 Pydantic 校验失败。"""
|
|
if value == "" or value == "null":
|
|
return None
|
|
return value
|
|
|
|
|
|
class ApiKeyCallableModel(BaseModel):
|
|
"""API Key 可调用模型配置。支持 camelCase 和 snake_case 两种字段名。"""
|
|
|
|
model_config = ConfigDict(populate_by_name=True)
|
|
|
|
engine_type: str = Field(..., description="video | image", alias="engineType")
|
|
engine_id: str = Field(..., description="引擎ID", alias="engineId")
|
|
model_name: str = Field(..., description="模型名称", alias="modelName")
|
|
|
|
|
|
class ApiKeyCreateRequest(BaseModel):
|
|
"""创建 API Key 请求。支持 camelCase 和 snake_case 两种字段名。"""
|
|
|
|
model_config = ConfigDict(populate_by_name=True)
|
|
|
|
company_name: str = Field(..., max_length=128, description="公司名称", alias="companyName")
|
|
description: str | None = Field(None, description="备注")
|
|
callable_models: list[ApiKeyCallableModel] = Field(
|
|
default_factory=list, description="可调用模型列表", alias="callableModels",
|
|
)
|
|
quota_limit: float | None = Field(None, description="配额总量,NULL=无限", alias="quotaLimit")
|
|
quota_cycle: str | None = Field(None, description="daily | monthly | one_time | NULL=无限", alias="quotaCycle")
|
|
valid_from: datetime | None = Field(None, description="生效时间", alias="validFrom")
|
|
valid_until: datetime | None = Field(None, description="过期时间", alias="validUntil")
|
|
max_concurrent_video_tasks: int | None = Field(
|
|
None, description="最大并发视频任务数", alias="maxConcurrentVideoTasks",
|
|
)
|
|
|
|
@field_validator("valid_from", "valid_until", mode="before")
|
|
@classmethod
|
|
def empty_str_to_none(cls, v):
|
|
if v == "" or v == "null" or v == 0:
|
|
return None
|
|
return v
|
|
|
|
|
|
class ApiKeyUpdateRequest(BaseModel):
|
|
"""更新 API Key 请求。支持 camelCase 和 snake_case 两种字段名。"""
|
|
|
|
model_config = ConfigDict(populate_by_name=True)
|
|
|
|
company_name: str | None = Field(None, max_length=128, alias="companyName")
|
|
description: str | None = None
|
|
callable_models: list[ApiKeyCallableModel] | None = Field(None, alias="callableModels")
|
|
quota_limit: float | None = Field(None, alias="quotaLimit")
|
|
quota_cycle: str | None = Field(None, alias="quotaCycle")
|
|
valid_from: datetime | None = Field(None, alias="validFrom")
|
|
valid_until: datetime | None = Field(None, alias="validUntil")
|
|
max_concurrent_video_tasks: int | None = Field(None, alias="maxConcurrentVideoTasks")
|
|
is_active: bool | None = Field(None, alias="isActive")
|
|
|
|
@field_validator("valid_from", "valid_until", mode="before")
|
|
@classmethod
|
|
def empty_str_to_none(cls, v):
|
|
if v == "" or v == "null" or v == 0:
|
|
return None
|
|
return v
|
|
|
|
|
|
class ApiKeyResponse(BaseModel):
|
|
"""API Key 详情响应。"""
|
|
|
|
id: str
|
|
company_name: str
|
|
api_key_prefix: str = Field(..., description="Key 前缀,如 vk_xxxx****")
|
|
description: str | None
|
|
callable_models: list[ApiKeyCallableModel]
|
|
quota_limit: float | None
|
|
quota_cycle: str | None
|
|
quota_used: float
|
|
valid_from: datetime | None
|
|
valid_until: datetime | None
|
|
max_concurrent_video_tasks: int | None
|
|
is_active: bool
|
|
last_used_at: datetime | None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ApiKeyCreateResponse(BaseModel):
|
|
"""创建 API Key 响应(包含完整明文 Key,仅此一次)。"""
|
|
|
|
id: str
|
|
company_name: str
|
|
api_key: str = Field(..., description="完整 API Key,仅创建时返回一次")
|
|
api_key_prefix: str
|
|
valid_until: datetime | None
|
|
created_at: datetime
|
|
|
|
|
|
class ApiKeyRevealResponse(BaseModel):
|
|
"""揭秘 API Key 响应(随时可获取明文)。"""
|
|
|
|
id: str
|
|
company_name: str
|
|
api_key: str = Field(..., description="完整 API Key")
|
|
api_key_prefix: str
|
|
|
|
|
|
class ApiKeyListItem(BaseModel):
|
|
"""API Key 列表项。"""
|
|
|
|
id: str
|
|
company_name: str
|
|
api_key_prefix: str
|
|
description: str | None
|
|
callable_models: list[ApiKeyCallableModel] = []
|
|
quota_limit: float | None
|
|
quota_cycle: str | None
|
|
quota_used: float
|
|
is_active: bool
|
|
valid_from: datetime | None
|
|
valid_until: datetime | None
|
|
max_concurrent_video_tasks: int | None
|
|
last_used_at: datetime | None
|
|
created_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ApiKeyListOut(BaseModel):
|
|
"""API Key 列表响应。"""
|
|
|
|
total: int
|
|
items: list[ApiKeyListItem]
|