Files

111 lines
3.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""请求 / 响应模型。"""
from __future__ import annotations
import re
from pydantic import BaseModel, Field, field_validator
from .config import PROFILE_RE
class ProviderIn(BaseModel):
id: str = Field(min_length=1, max_length=64)
name: str = Field(min_length=1, max_length=100)
adapter: str = Field(default="openai_compat")
base_url: str = Field(min_length=1)
api_key: str = ""
default_model: str = ""
enabled: bool = True
note: str = ""
@field_validator("id")
@classmethod
def check_id(cls, v: str) -> str:
v = v.strip()
if not PROFILE_RE.match(v):
raise ValueError("供应商 ID 只能包含字母数字下划线和短横线")
return v
@field_validator("adapter")
@classmethod
def check_adapter(cls, v: str) -> str:
if v not in ("openai_compat", "agnes"):
raise ValueError("不支持的适配器类型")
return v
@field_validator("base_url")
@classmethod
def check_base_url(cls, v: str) -> str:
v = v.strip().rstrip("/")
if not v.startswith("http://") and not v.startswith("https://"):
raise ValueError("Base URL 必须以 http:// 或 https:// 开头")
return v
class DiscoverIn(BaseModel):
"""手动填写 Base URL + Key 时的临时发现(供应商尚未保存)。"""
adapter: str = "openai_compat"
base_url: str = Field(min_length=1)
api_key: str = Field(min_length=1)
check_adapter = field_validator("adapter")(ProviderIn.check_adapter.__func__)
check_base_url = field_validator("base_url")(ProviderIn.check_base_url.__func__)
class ModelUpsertIn(BaseModel):
model_ids: list[str] = Field(default_factory=list)
enabled: bool = True
note: str = ""
class ModelPatchIn(BaseModel):
enabled: bool | None = None
note: str | None = None
class ModelBulkIn(BaseModel):
ids: list[str] = Field(default_factory=list)
enabled: bool
class GenerateIn(BaseModel):
provider_id: str = Field(min_length=1)
model: str = Field(min_length=1)
prompt: str = Field(min_length=1)
size: str = "1024x1024"
ratio: str = ""
n: int = Field(default=1, ge=1, le=4)
images: list[str] = Field(default_factory=list)
profile_name: str | None = None
@field_validator("size")
@classmethod
def check_size(cls, v: str) -> str:
v = v.strip().upper()
if v in ("1K", "2K", "3K", "4K"):
return v
match = re.fullmatch(r"([1-9]\d{0,4})[X×]([1-9]\d{0,4})", v)
if not match:
raise ValueError("尺寸必须为正整数 WxH 或 1K/2K/3K/4K")
return f"{int(match[1])}x{int(match[2])}"
@field_validator("profile_name")
@classmethod
def check_profile(cls, v: str | None) -> str | None:
if v is None or v == "":
return None
v = v.strip()
if not PROFILE_RE.match(v):
raise ValueError("profile_name 只能包含字母数字下划线和短横线")
return v
@field_validator("prompt")
@classmethod
def check_prompt(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("提示词不能为空")
return v