mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-31 16:50:17 +08:00
Finished @ROUTES.put(f"/api/assets/{{id:{UUID_RE}}}")
This commit is contained in:
parent
6db4f4e3f1
commit
e0c063f93e
@ -350,3 +350,33 @@ async def upload_asset(request: web.Request) -> web.Response:
|
|||||||
logging.exception("upload_asset_from_temp_path failed for tmp_path=%s, owner_id=%s", tmp_path, owner_id)
|
logging.exception("upload_asset_from_temp_path failed for tmp_path=%s, owner_id=%s", tmp_path, owner_id)
|
||||||
return _error_response(500, "INTERNAL", "Unexpected server error.")
|
return _error_response(500, "INTERNAL", "Unexpected server error.")
|
||||||
|
|
||||||
|
|
||||||
|
@ROUTES.put(f"/api/assets/{{id:{UUID_RE}}}")
|
||||||
|
async def update_asset(request: web.Request) -> web.Response:
|
||||||
|
asset_info_id = str(uuid.UUID(request.match_info["id"]))
|
||||||
|
try:
|
||||||
|
body = schemas_in.UpdateAssetBody.model_validate(await request.json())
|
||||||
|
except ValidationError as ve:
|
||||||
|
return _validation_error_response("INVALID_BODY", ve)
|
||||||
|
except Exception:
|
||||||
|
return _error_response(400, "INVALID_JSON", "Request body must be valid JSON.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = manager.update_asset(
|
||||||
|
asset_info_id=asset_info_id,
|
||||||
|
name=body.name,
|
||||||
|
tags=body.tags,
|
||||||
|
user_metadata=body.user_metadata,
|
||||||
|
owner_id=USER_MANAGER.get_request_user_id(request),
|
||||||
|
)
|
||||||
|
except (ValueError, PermissionError) as ve:
|
||||||
|
return _error_response(404, "ASSET_NOT_FOUND", str(ve), {"id": asset_info_id})
|
||||||
|
except Exception:
|
||||||
|
logging.exception(
|
||||||
|
"update_asset failed for asset_info_id=%s, owner_id=%s",
|
||||||
|
asset_info_id,
|
||||||
|
USER_MANAGER.get_request_user_id(request),
|
||||||
|
)
|
||||||
|
return _error_response(500, "INTERNAL", "Unexpected server error.")
|
||||||
|
return web.json_response(result.model_dump(mode="json"), status=200)
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,21 @@ class ListAssetsQuery(BaseModel):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateAssetBody(BaseModel):
|
||||||
|
name: str | None = None
|
||||||
|
tags: list[str] | None = None
|
||||||
|
user_metadata: dict[str, Any] | None = None
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def _at_least_one(self):
|
||||||
|
if self.name is None and self.tags is None and self.user_metadata is None:
|
||||||
|
raise ValueError("Provide at least one of: name, tags, user_metadata.")
|
||||||
|
if self.tags is not None:
|
||||||
|
if not isinstance(self.tags, list) or not all(isinstance(t, str) for t in self.tags):
|
||||||
|
raise ValueError("Field 'tags' must be an array of strings.")
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
class CreateFromHashBody(BaseModel):
|
class CreateFromHashBody(BaseModel):
|
||||||
model_config = ConfigDict(extra="ignore", str_strip_whitespace=True)
|
model_config = ConfigDict(extra="ignore", str_strip_whitespace=True)
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,21 @@ class AssetsList(BaseModel):
|
|||||||
has_more: bool
|
has_more: bool
|
||||||
|
|
||||||
|
|
||||||
|
class AssetUpdated(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
asset_hash: str | None = None
|
||||||
|
tags: list[str] = Field(default_factory=list)
|
||||||
|
user_metadata: dict[str, Any] = Field(default_factory=dict)
|
||||||
|
updated_at: datetime | None = None
|
||||||
|
|
||||||
|
model_config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
|
@field_serializer("updated_at")
|
||||||
|
def _ser_updated(self, v: datetime | None, _info):
|
||||||
|
return v.isoformat() if v else None
|
||||||
|
|
||||||
|
|
||||||
class AssetDetail(BaseModel):
|
class AssetDetail(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
name: str
|
name: str
|
||||||
|
|||||||
@ -652,6 +652,71 @@ def ingest_fs_asset(
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def update_asset_info_full(
|
||||||
|
session: Session,
|
||||||
|
*,
|
||||||
|
asset_info_id: str,
|
||||||
|
name: str | None = None,
|
||||||
|
tags: Sequence[str] | None = None,
|
||||||
|
user_metadata: dict | None = None,
|
||||||
|
tag_origin: str = "manual",
|
||||||
|
asset_info_row: Any = None,
|
||||||
|
) -> AssetInfo:
|
||||||
|
if not asset_info_row:
|
||||||
|
info = session.get(AssetInfo, asset_info_id)
|
||||||
|
if not info:
|
||||||
|
raise ValueError(f"AssetInfo {asset_info_id} not found")
|
||||||
|
else:
|
||||||
|
info = asset_info_row
|
||||||
|
|
||||||
|
touched = False
|
||||||
|
if name is not None and name != info.name:
|
||||||
|
info.name = name
|
||||||
|
touched = True
|
||||||
|
|
||||||
|
computed_filename = None
|
||||||
|
try:
|
||||||
|
p = pick_best_live_path(list_cache_states_by_asset_id(session, asset_id=info.asset_id))
|
||||||
|
if p:
|
||||||
|
computed_filename = compute_relative_filename(p)
|
||||||
|
except Exception:
|
||||||
|
computed_filename = None
|
||||||
|
|
||||||
|
if user_metadata is not None:
|
||||||
|
new_meta = dict(user_metadata)
|
||||||
|
if computed_filename:
|
||||||
|
new_meta["filename"] = computed_filename
|
||||||
|
replace_asset_info_metadata_projection(
|
||||||
|
session, asset_info_id=asset_info_id, user_metadata=new_meta
|
||||||
|
)
|
||||||
|
touched = True
|
||||||
|
else:
|
||||||
|
if computed_filename:
|
||||||
|
current_meta = info.user_metadata or {}
|
||||||
|
if current_meta.get("filename") != computed_filename:
|
||||||
|
new_meta = dict(current_meta)
|
||||||
|
new_meta["filename"] = computed_filename
|
||||||
|
replace_asset_info_metadata_projection(
|
||||||
|
session, asset_info_id=asset_info_id, user_metadata=new_meta
|
||||||
|
)
|
||||||
|
touched = True
|
||||||
|
|
||||||
|
if tags is not None:
|
||||||
|
set_asset_info_tags(
|
||||||
|
session,
|
||||||
|
asset_info_id=asset_info_id,
|
||||||
|
tags=tags,
|
||||||
|
origin=tag_origin,
|
||||||
|
)
|
||||||
|
touched = True
|
||||||
|
|
||||||
|
if touched and user_metadata is None:
|
||||||
|
info.updated_at = utcnow()
|
||||||
|
session.flush()
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
def list_tags_with_usage(
|
def list_tags_with_usage(
|
||||||
session: Session,
|
session: Session,
|
||||||
prefix: str | None = None,
|
prefix: str | None = None,
|
||||||
|
|||||||
@ -8,10 +8,12 @@ from app.assets.api import schemas_out, schemas_in
|
|||||||
from app.assets.database.queries import (
|
from app.assets.database.queries import (
|
||||||
asset_exists_by_hash,
|
asset_exists_by_hash,
|
||||||
get_asset_by_hash,
|
get_asset_by_hash,
|
||||||
|
get_asset_info_by_id,
|
||||||
fetch_asset_info_asset_and_tags,
|
fetch_asset_info_asset_and_tags,
|
||||||
fetch_asset_info_and_asset,
|
fetch_asset_info_and_asset,
|
||||||
create_asset_info_for_existing_asset,
|
create_asset_info_for_existing_asset,
|
||||||
touch_asset_info_by_id,
|
touch_asset_info_by_id,
|
||||||
|
update_asset_info_full,
|
||||||
list_cache_states_by_asset_id,
|
list_cache_states_by_asset_id,
|
||||||
list_asset_infos_page,
|
list_asset_infos_page,
|
||||||
list_tags_with_usage,
|
list_tags_with_usage,
|
||||||
@ -278,6 +280,44 @@ def upload_asset_from_temp_path(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def update_asset(
|
||||||
|
*,
|
||||||
|
asset_info_id: str,
|
||||||
|
name: str | None = None,
|
||||||
|
tags: list[str] | None = None,
|
||||||
|
user_metadata: dict | None = None,
|
||||||
|
owner_id: str = "",
|
||||||
|
) -> schemas_out.AssetUpdated:
|
||||||
|
with create_session() as session:
|
||||||
|
info_row = get_asset_info_by_id(session, asset_info_id=asset_info_id)
|
||||||
|
if not info_row:
|
||||||
|
raise ValueError(f"AssetInfo {asset_info_id} not found")
|
||||||
|
if info_row.owner_id and info_row.owner_id != owner_id:
|
||||||
|
raise PermissionError("not owner")
|
||||||
|
|
||||||
|
info = update_asset_info_full(
|
||||||
|
session,
|
||||||
|
asset_info_id=asset_info_id,
|
||||||
|
name=name,
|
||||||
|
tags=tags,
|
||||||
|
user_metadata=user_metadata,
|
||||||
|
tag_origin="manual",
|
||||||
|
asset_info_row=info_row,
|
||||||
|
)
|
||||||
|
|
||||||
|
tag_names = get_asset_tags(session, asset_info_id=asset_info_id)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
return schemas_out.AssetUpdated(
|
||||||
|
id=info.id,
|
||||||
|
name=info.name,
|
||||||
|
asset_hash=info.asset.hash if info.asset else None,
|
||||||
|
tags=tag_names,
|
||||||
|
user_metadata=info.user_metadata or {},
|
||||||
|
updated_at=info.updated_at,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_asset_from_hash(
|
def create_asset_from_hash(
|
||||||
*,
|
*,
|
||||||
hash_str: str,
|
hash_str: str,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user