chore: import upstream snapshot with attribution
Validate YAML Workflows / Validate YAML Configuration Files (push) Has been cancelled
Validate YAML Workflows / Validate YAML Configuration Files (push) Has been cancelled
This commit is contained in:
Executable
+71
@@ -0,0 +1,71 @@
|
||||
"""FastAPI router for dynamic configuration schema endpoints."""
|
||||
|
||||
from typing import Any, Dict, List, Mapping
|
||||
|
||||
import yaml
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from entity.config_loader import load_design_from_mapping
|
||||
from entity.configs import ConfigError
|
||||
from utils.schema_exporter import build_schema_response, SchemaResolutionError
|
||||
|
||||
|
||||
router = APIRouter(prefix="/api/config", tags=["config-schema"])
|
||||
|
||||
|
||||
class SchemaRequest(BaseModel):
|
||||
breadcrumbs: List[Mapping[str, Any]] | None = Field(
|
||||
default=None,
|
||||
description="Breadcrumb path starting from DesignConfig, e.g. [{\"node\":\"DesignConfig\",\"field\":\"graph\"}]",
|
||||
)
|
||||
|
||||
|
||||
class SchemaValidateRequest(SchemaRequest):
|
||||
document: str = Field(..., description="Full YAML/JSON content")
|
||||
|
||||
|
||||
def _resolve_schema(breadcrumbs: List[Mapping[str, Any]] | None) -> Dict[str, Any] | None:
|
||||
if not breadcrumbs:
|
||||
return None
|
||||
try:
|
||||
return build_schema_response(breadcrumbs)
|
||||
except SchemaResolutionError:
|
||||
return None
|
||||
|
||||
|
||||
@router.post("/schema")
|
||||
def get_schema(request: SchemaRequest) -> Dict[str, Any]:
|
||||
try:
|
||||
return build_schema_response(request.breadcrumbs)
|
||||
except SchemaResolutionError as exc:
|
||||
raise HTTPException(status_code=422, detail={"message": str(exc)}) from exc
|
||||
|
||||
|
||||
@router.post("/schema/validate")
|
||||
def validate_document(request: SchemaValidateRequest) -> Dict[str, Any]:
|
||||
try:
|
||||
parsed = yaml.safe_load(request.document)
|
||||
except yaml.YAMLError as exc:
|
||||
raise HTTPException(status_code=400, detail={"message": "invalid_yaml", "error": str(exc)}) from exc
|
||||
|
||||
if not isinstance(parsed, Mapping):
|
||||
raise HTTPException(status_code=422, detail={"message": "document_root_not_mapping"})
|
||||
|
||||
try:
|
||||
load_design_from_mapping(parsed)
|
||||
except ConfigError as exc:
|
||||
return {
|
||||
"valid": False,
|
||||
"error": str(exc),
|
||||
"path": exc.path,
|
||||
"schema": _resolve_schema(request.breadcrumbs),
|
||||
}
|
||||
|
||||
return {
|
||||
"valid": True,
|
||||
"schema": _resolve_schema(request.breadcrumbs),
|
||||
}
|
||||
|
||||
|
||||
__all__ = ["router"]
|
||||
Reference in New Issue
Block a user