Skip to main content
Glama
validation.py18.6 kB
""" Seedream MCP工具 - 参数验证模块 提供标准化的参数验证函数,用于验证文本提示词、图像尺寸、图像路径等参数。 所有验证函数在参数不符合规范时会抛出SeedreamValidationError异常。 """ # 标准库导入 import io import re from pathlib import Path from typing import Any, List from urllib.parse import urlparse # 第三方库导入 from PIL import Image # 本地模块导入 from .errors import SeedreamValidationError def validate_prompt(prompt: str, max_chinese_chars: int = 300, max_english_words: int = 600) -> str: """验证文本提示词的有效性和长度限制 当中文字符超过 `max_chinese_chars` 或英文单词超过 `max_english_words` 时,视为过长。 """ if not prompt or not isinstance(prompt, str): raise SeedreamValidationError("提示词不能为空", field="prompt", value=prompt) prompt = prompt.strip() if not prompt: raise SeedreamValidationError("提示词不能为空", field="prompt", value=prompt) chinese_count = len(re.findall(r"[\u4e00-\u9fff]", prompt)) english_word_count = len(re.findall(r"[A-Za-z]+(?:'[A-Za-z]+)?", prompt)) if chinese_count > max_chinese_chars or english_word_count > max_english_words: raise SeedreamValidationError( ( f"提示词过长,建议不超过{max_chinese_chars}个汉字或{max_english_words}个英文单词" f"(当前中文{chinese_count}个,英文{english_word_count}个)" ), field="prompt", value=prompt, ) return prompt def validate_size(size: str) -> str: """验证图像尺寸参数是否在允许的范围内 Args: size: 图像尺寸规格,支持 1K/2K/4K Returns: str: 标准化后的尺寸值(大写格式) Raises: SeedreamValidationError: 当尺寸参数无效时抛出 """ valid_sizes = ["1K", "2K", "4K"] if not size or not isinstance(size, str): raise SeedreamValidationError("图像尺寸不能为空", field="size", value=size) size = size.strip().upper() if size not in valid_sizes: raise SeedreamValidationError( f"图像尺寸必须是以下值之一: {valid_sizes}", field="size", value=size ) return size def validate_size_for_model(size: str, model_id: str) -> str: """验证图像尺寸与模型的兼容性 不同模型对图像尺寸有特定要求,此函数确保尺寸参数符合模型限制。 Args: size: 图像尺寸规格 model_id: 模型标识符 Returns: str: 验证通过的尺寸值 Raises: SeedreamValidationError: 当尺寸与模型不兼容时抛出 """ size = validate_size(size) mid = (model_id or "").lower() # doubao-seedream-4.5 模型仅支持 2K/4K if "doubao-seedream-4-5" in mid or "doubao-seedream-4.5" in mid: if size not in {"2K", "4K"}: raise SeedreamValidationError( "在 doubao-seedream-4.5 模型下仅支持 2K/4K", field="size", value=size, ) return size def validate_optimize_prompt_options(options: Any, model_id: str) -> dict | None: """验证提示词优化选项的配置 检查优化模式是否有效,并确保与模型兼容。 Args: options: 优化选项字典,包含mode等配置 model_id: 模型标识符 Returns: dict | None: 验证后的优化选项字典,若输入为None则返回None Raises: SeedreamValidationError: 当选项配置无效或与模型不兼容时抛出 """ if options is None: return None if not isinstance(options, dict): raise SeedreamValidationError( "optimize_prompt_options必须为对象", field="optimize_prompt_options", value=options ) mode = options.get("mode", "standard") if not isinstance(mode, str): raise SeedreamValidationError( "optimize_prompt_options.mode必须为字符串", field="optimize_prompt_options.mode", value=mode, ) mode = mode.strip().lower() allowed = {"standard", "fast"} if mode not in allowed: raise SeedreamValidationError( f"optimize_prompt_options.mode 必须为 {sorted(list(allowed))}", field="optimize_prompt_options.mode", value=mode, ) # doubao-seedream-4.5 模型仅支持 standard 模式 mid = (model_id or "").lower() if "doubao-seedream-4-5" in mid or "doubao-seedream-4.5" in mid: if mode != "standard": raise SeedreamValidationError( "doubao-seedream-4.5 当前仅支持 optimize_prompt_options.mode=standard", field="optimize_prompt_options.mode", value=mode, ) return {"mode": mode} def validate_image_url(image: str) -> str: """验证图像URL、文件路径或Data URI的有效性 支持三种图像输入格式: - HTTP/HTTPS URL - 本地文件路径 - Data URI(base64编码) Args: image: 图像URL、文件路径或Data URI Returns: str: 验证通过的图像路径 Raises: SeedreamValidationError: 当图像路径格式无效或不可访问时抛出 """ if not image or not isinstance(image, str): raise SeedreamValidationError("图像路径不能为空", field="image", value=image) image = image.strip() if not image: raise SeedreamValidationError("图像路径不能为空", field="image", value=image) # Data URI 格式验证 if image.lower().startswith("data:image/"): return _validate_data_uri(image) # HTTP/HTTPS URL 验证 if image.startswith(("http://", "https://")): return _validate_url(image) # 本地文件路径验证 return _validate_file_path(image) def validate_image_list(images: List[str], min_count: int = 1, max_count: int = 5) -> List[str]: """验证图像路径列表的有效性和数量限制 对列表中的每个图像路径进行验证,并检查总数是否在允许范围内。 Args: images: 图像URL或文件路径列表 min_count: 最小图像数量,默认为1 max_count: 最大图像数量,默认为5 Returns: List[str]: 验证通过的图像路径列表 Raises: SeedreamValidationError: 当列表为空、数量超限或任一路径无效时抛出 """ if not images or not isinstance(images, list): raise SeedreamValidationError("图像列表不能为空", field="images", value=images) if len(images) < min_count: raise SeedreamValidationError( f"图像数量不能少于{min_count}张", field="images", value=images ) if len(images) > max_count: raise SeedreamValidationError( f"图像数量不能超过{max_count}张", field="images", value=images ) # 逐个验证图像路径 validated_images = [] for i, image in enumerate(images): try: validated_image = validate_image_url(image) validated_images.append(validated_image) except SeedreamValidationError as e: raise SeedreamValidationError( f"第{i+1}张图像验证失败: {e.message}", field=f"images[{i}]", value=image ) return validated_images def validate_max_images(max_images: Any) -> int: """验证最大图像数量参数 确保参数为整数类型且在合理范围内(1-15)。 Args: max_images: 最大图像数量,支持整数或可转换为整数的值 Returns: int: 验证后的整数值 Raises: SeedreamValidationError: 当参数类型错误或超出范围时抛出 """ if isinstance(max_images, int): validated_value = max_images else: try: validated_value = int(max_images) except (ValueError, TypeError): raise SeedreamValidationError( "最大图像数量必须是整数", field="max_images", value=max_images ) if validated_value < 1: raise SeedreamValidationError( "最大图像数量不能小于1", field="max_images", value=validated_value ) if validated_value > 15: raise SeedreamValidationError( "最大图像数量不能超过15", field="max_images", value=validated_value ) return validated_value def validate_watermark(watermark: Any) -> bool: """验证水印参数配置 支持布尔值或可转换为布尔值的字符串(true/false、yes/no、on/off、1/0)。 Args: watermark: 水印开关配置,支持bool或str类型 Returns: bool: 标准化后的布尔值 Raises: SeedreamValidationError: 当参数类型或格式无效时抛出 """ if isinstance(watermark, bool): return watermark if isinstance(watermark, str): watermark_lower = watermark.lower().strip() if watermark_lower in ("true", "1", "yes", "on"): return True elif watermark_lower in ("false", "0", "no", "off"): return False else: raise SeedreamValidationError( "水印参数必须是布尔值或有效的字符串(true/false)", field="watermark", value=watermark, ) raise SeedreamValidationError("水印参数必须是布尔值", field="watermark", value=watermark) def validate_response_format(response_format: str) -> str: """验证响应格式参数 Args: response_format: 响应格式类型,支持 url 或 b64_json Returns: str: 标准化后的格式值(小写) Raises: SeedreamValidationError: 当格式参数无效时抛出 """ valid_formats = ["url", "b64_json"] if not response_format or not isinstance(response_format, str): raise SeedreamValidationError( "响应格式不能为空", field="response_format", value=response_format ) response_format = response_format.strip().lower() if response_format not in valid_formats: raise SeedreamValidationError( f"响应格式必须是以下值之一: {valid_formats}", field="response_format", value=response_format, ) return response_format # ==================== 私有辅助函数 ==================== def _validate_url(url: str) -> str: """验证HTTP/HTTPS URL的格式正确性 检查URL的scheme、netloc等部分是否完整,并对图像扩展名进行简单校验。 Args: url: 待验证的URL字符串 Returns: str: 原始URL(验证通过) Raises: SeedreamValidationError: 当URL格式无效时抛出 """ try: parsed = urlparse(url) if not parsed.scheme or not parsed.netloc: raise SeedreamValidationError("无效的URL格式", field="image", value=url) # 检查URL路径中的图像扩展名 if parsed.path: path_lower = parsed.path.lower() image_extensions = [".jpeg", ".png", ".gif", ".bmp", ".webp", ".tiff"] if not any(path_lower.endswith(ext) for ext in image_extensions): # 没有明显的图像扩展名,给出警告但不阻止 pass return url except Exception as e: raise SeedreamValidationError(f"URL验证失败: {str(e)}", field="image", value=url) def _validate_file_path(file_path: str) -> str: """验证本地文件路径的存在性、格式和尺寸限制 执行以下检查: - 文件是否存在 - 是否为有效文件(而非目录) - 文件扩展名是否支持 - 文件大小是否超过10MB - 图像尺寸是否符合要求(宽高>14px,宽高比在1/16到16之间,总像素≤6000×6000) Args: file_path: 本地文件的完整路径 Returns: str: 文件的绝对路径 Raises: SeedreamValidationError: 当文件不存在、格式不支持或尺寸超限时抛出 """ try: path = Path(file_path) # 检查文件是否存在 if not path.exists(): raise SeedreamValidationError( f"文件不存在: {file_path}", field="image", value=file_path ) # 检查是否为文件 if not path.is_file(): raise SeedreamValidationError( f"路径不是文件: {file_path}", field="image", value=file_path ) # 检查文件扩展名 image_extensions = [".jpeg", ".png", ".gif", ".bmp", ".webp", ".tiff"] if path.suffix.lower() not in image_extensions: raise SeedreamValidationError( f"不支持的图像格式: {path.suffix},支持的格式: {image_extensions}", field="image", value=file_path, ) # 检查文件大小(限制为10MB) file_size = path.stat().st_size max_size = 10 * 1024 * 1024 if file_size > max_size: raise SeedreamValidationError( f"文件过大: {file_size / 1024 / 1024:.1f}MB,最大支持10MB", field="image", value=file_path, ) # 验证图像像素维度约束 try: with Image.open(path) as img: w, h = img.size # 宽高必须大于14像素 if w <= 14 or h <= 14: raise SeedreamValidationError( "图像宽高长度必须大于14px", field="image", value=file_path, ) # 宽高比限制在 1/16 到 16 之间 ratio = w / h if h else 0 if ratio < (1 / 16) or ratio > 16: raise SeedreamValidationError( "图像宽高比需在[1/16, 16]范围内", field="image", value=file_path, ) # 总像素不超过 6000×6000 if w * h > 6000 * 6000: raise SeedreamValidationError( "图像总像素不能超过 6000×6000", field="image", value=file_path, ) except SeedreamValidationError: raise except Exception as e: raise SeedreamValidationError( f"图像维度解析失败: {str(e)}", field="image", value=file_path, ) return str(path.absolute()) except SeedreamValidationError: raise except Exception as e: raise SeedreamValidationError(f"文件路径验证失败: {str(e)}", field="image", value=file_path) def _validate_data_uri(data_uri: str) -> str: """验证Data URI格式的图像数据 执行以下检查: - Data URI格式是否正确(data:image/<格式>;base64,<数据>) - 图像格式是否支持 - Base64数据是否可解码 - 解码后数据大小是否超过10MB - 图像尺寸是否符合要求(宽高>14px,宽高比在1/16到16之间,总像素≤6000×6000) Args: data_uri: Data URI格式的图像字符串 Returns: str: 原始Data URI(验证通过) Raises: SeedreamValidationError: 当格式无效、数据损坏或尺寸超限时抛出 """ try: # 解析Data URI结构 header, _, b64 = data_uri.partition(",") if not header or not b64: raise SeedreamValidationError("Data URI 格式无效", field="image", value=data_uri) # 验证Header格式 header_lower = header.lower() if not header_lower.startswith("data:image/") or ";base64" not in header_lower: raise SeedreamValidationError( "Data URI 必须为 data:image/<格式>;base64, 前缀且小写", field="image", value=data_uri, ) # 提取并验证图像格式 fmt = header_lower.split("data:image/")[-1].split(";")[0] allowed = {"jpeg", "png", "webp", "bmp", "tiff", "gif"} if fmt not in allowed: raise SeedreamValidationError( f"不支持的Data URI图片格式: {fmt}", field="image", value=data_uri ) # Base64解码 try: import base64 raw = base64.b64decode(b64, validate=True) except Exception as e: raise SeedreamValidationError( f"Base64 解码失败: {str(e)}", field="image", value=data_uri ) # 检查数据大小 size_bytes = len(raw) if size_bytes > 10 * 1024 * 1024: raise SeedreamValidationError( f"数据过大: {size_bytes / 1024 / 1024:.1f}MB,最大支持10MB", field="image", value=data_uri, ) # 验证图像像素维度约束 try: with Image.open(io.BytesIO(raw)) as img: w, h = img.size # 宽高必须大于14像素 if w <= 14 or h <= 14: raise SeedreamValidationError( "图像宽高长度必须大于14px", field="image", value=data_uri ) # 宽高比限制在 1/16 到 16 之间 ratio = w / h if h else 0 if ratio < (1 / 16) or ratio > 16: raise SeedreamValidationError( "图像宽高比需在[1/16, 16]范围内", field="image", value=data_uri ) # 总像素不超过 6000×6000 if w * h > 6000 * 6000: raise SeedreamValidationError( "图像总像素不能超过 6000×6000", field="image", value=data_uri ) except SeedreamValidationError: raise except Exception as e: raise SeedreamValidationError( f"图像维度解析失败: {str(e)}", field="image", value=data_uri ) return data_uri except SeedreamValidationError: raise except Exception as e: raise SeedreamValidationError(f"Data URI 验证失败: {str(e)}", field="image", value=data_uri)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tengmmvp/Seedream_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server