diff --git a/invokeai/app/util/custom_openapi.py b/invokeai/app/util/custom_openapi.py index fd89fe2cc09..f674fa76218 100644 --- a/invokeai/app/util/custom_openapi.py +++ b/invokeai/app/util/custom_openapi.py @@ -30,6 +30,23 @@ def move_defs_to_top_level(openapi_schema: dict[str, Any], component_schema: dic openapi_schema["components"]["schemas"][schema_key] = json_schema +def normalize_path_defaults(node: Any) -> None: + """Recursively normalize `default` strings on schema nodes whose `format` is `path` to use forward slashes. + + Pydantic stringifies `Path` defaults using the host OS's separator, so a default declared as + `Path("models/.convert_cache")` serializes to `models\\.convert_cache` on Windows. That OS-dependent drift + pollutes diffs whenever schema is regenerated on Windows. We force POSIX form for path-typed defaults. + """ + if isinstance(node, dict): + if node.get("format") == "path" and isinstance(node.get("default"), str): + node["default"] = node["default"].replace("\\", "/") + for v in node.values(): + normalize_path_defaults(v) + elif isinstance(node, list): + for v in node: + normalize_path_defaults(v) + + def get_openapi_func( app: FastAPI, post_transform: Optional[Callable[[dict[str, Any]], dict[str, Any]]] = None ) -> Callable[[], dict[str, Any]]: @@ -126,6 +143,8 @@ def openapi() -> dict[str, Any]: if post_transform is not None: openapi_schema = post_transform(openapi_schema) + normalize_path_defaults(openapi_schema) + openapi_schema["components"]["schemas"] = dict(sorted(openapi_schema["components"]["schemas"].items())) app.openapi_schema = openapi_schema