Files
Unraid-AppOps-Gateway-Public/backend/app/api/routes_privatemuse_artifacts.py
T

140 lines
4.1 KiB
Python

from __future__ import annotations
import os
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, ConfigDict, Field
from sqlmodel import Session
from ..db.session import get_session
from ..services.audit_logger import log_event
from ..services.policy_engine import evaluate_policy
from ..services.privatemuse_artifact_installer import (
ArtifactInstallError,
install,
validate_request,
)
router = APIRouter(prefix="/api/privatemuse/artifacts")
class ArtifactInstallRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
artifact_type: str = Field(pattern="^(lora|checkpoint|unet|vae|clip|gguf)$")
source_url: str = Field(min_length=9, max_length=2048)
sha256: str = Field(pattern="^[0-9a-f]{64}$")
filename: str = Field(min_length=13, max_length=192)
source_id: str = Field(min_length=1, max_length=240)
license: str = Field(min_length=1, max_length=240)
reason: str = Field(min_length=1, max_length=1000)
@router.post("/preflight")
def preflight(
payload: ArtifactInstallRequest,
session: Session = Depends(get_session),
):
action = "privatemuse.comfyui.install_artifact"
target = "privatemuse/comfyui"
decision = evaluate_policy(
session,
action=action,
target=target,
source="manual",
)
try:
normalized = validate_request(payload.model_dump())
except ArtifactInstallError as exc:
raise HTTPException(422, str(exc)) from exc
return {
"ready": decision["decision"] != "blocked",
"policy": decision,
"artifact": {
"artifact_type": normalized["artifact_type"],
"filename": normalized["filename"],
"sha256": normalized["sha256"],
"source_id": normalized["source_id"],
"source_host": normalized["source_url"].split("/")[2],
"license": normalized["license"],
},
}
@router.post("/install")
def install_artifact(
payload: ArtifactInstallRequest,
session: Session = Depends(get_session),
):
action = "privatemuse.comfyui.install_artifact"
target = "privatemuse/comfyui"
decision = evaluate_policy(
session,
action=action,
target=target,
source="manual",
)
if decision["decision"] != "allowed":
raise HTTPException(
409,
"Artifact installation requires an explicitly allowed policy/approved execution context.",
)
model_root = Path(
os.environ.get(
"APPOPS_PRIVATEMUSE_COMFYUI_MODEL_ROOT",
"/mnt/privatemuse-comfyui-models",
)
)
receipt_root = Path(
os.environ.get(
"APPOPS_PRIVATEMUSE_ARTIFACT_RECEIPT_ROOT",
"/data/privatemuse-artifact-receipts",
)
)
try:
result = install(
payload.model_dump(),
model_root=model_root,
receipt_root=receipt_root,
)
except ArtifactInstallError as exc:
log_event(
session,
source="action",
identity="manual",
action_id=action,
target=target,
risk="high",
policy_decision="allowed",
reason=payload.reason,
result="failed",
redacted_metadata={
"filename": payload.filename,
"sha256": payload.sha256,
"source_id": payload.source_id,
},
)
raise HTTPException(409, str(exc)) from exc
audit = log_event(
session,
source="action",
identity="manual",
action_id=action,
target=target,
risk="high",
policy_decision="allowed",
reason=payload.reason,
result="success",
after_state={
"status": result["status"],
"sha256": result["sha256"],
"bytes": result["bytes"],
},
redacted_metadata={
"filename": payload.filename,
"source_id": payload.source_id,
"license": payload.license,
},
)
return {**result, "auditId": audit.id}