Trim verbose comments on listAssets query fields
This commit is contained in:
parent
9bab190e6b
commit
3b21f218a3
|
|
@ -54,16 +54,11 @@ class ListAssetsQuery(BaseModel):
|
|||
exclude_tags: list[str] = Field(default_factory=list)
|
||||
name_contains: str | None = None
|
||||
|
||||
# Filter to assets whose content hash matches exactly. Param name is `hash`
|
||||
# per the projected openapi.yaml listAssets contract (the response-body field
|
||||
# is `asset_hash`; the query param is `hash`).
|
||||
# Filter by exact content hash (emitted as `asset_hash` in responses)
|
||||
hash: str | None = None
|
||||
|
||||
# Declared for cloud/core contract parity. In core, reads are owner-scoped
|
||||
# (owner_id == "") and there is no separate shared/public pool for this flag
|
||||
# to include or exclude, so it is inert here and intentionally not threaded
|
||||
# into the query. Accepted (not rejected) so the FE needs no isCloud branch;
|
||||
# cloud enforces the flag in its own service layer.
|
||||
# Accepted for API compatibility; has no effect, as there is no shared
|
||||
# asset pool to include or exclude
|
||||
include_public: bool = True
|
||||
|
||||
# Accept either a JSON string (query param) or a dict
|
||||
|
|
@ -101,12 +96,7 @@ class ListAssetsQuery(BaseModel):
|
|||
@field_validator("hash", mode="before")
|
||||
@classmethod
|
||||
def _normalize_hash(cls, v):
|
||||
# Normalize for an exact match against stored hashes (which are
|
||||
# lowercase `blake3:<hex>`). Liberal in what we accept — no pattern
|
||||
# enforcement; a non-matching value simply yields an empty page.
|
||||
# An explicitly-supplied-but-empty value (`?hash=`) stays `""` so it
|
||||
# is treated as an exact-match miss (empty page), not silently dropped
|
||||
# to "no filter" — omit the param entirely to disable the filter.
|
||||
# Stored hashes are lowercase `blake3:<hex>`; no pattern is enforced
|
||||
if isinstance(v, str):
|
||||
return v.strip().lower()
|
||||
return v
|
||||
|
|
|
|||
|
|
@ -294,8 +294,7 @@ def list_references_page(
|
|||
escaped, esc = escape_sql_like_string(name_contains)
|
||||
base = base.where(AssetReference.name.ilike(f"%{escaped}%", escape=esc))
|
||||
|
||||
# `is not None` (not truthiness): an explicit empty hash is an exact-match
|
||||
# miss (empty page), while an omitted hash (None) disables the filter.
|
||||
# Not truthiness: an empty hash matches nothing, an omitted one filters nothing
|
||||
if asset_hash is not None:
|
||||
base = base.where(Asset.hash == asset_hash)
|
||||
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ def test_list_assets_invalid_query_rejected(http: requests.Session, api_base: st
|
|||
|
||||
def test_list_assets_display_name_emitted(http, api_base, asset_factory, make_asset_bytes):
|
||||
"""`display_name` is emitted for every populated asset in list responses,
|
||||
derived from the storage path (category prefix + hash-based stored filename)."""
|
||||
derived from the storage path."""
|
||||
scope = f"lf-dispname-{uuid.uuid4().hex[:6]}"
|
||||
tags = ["models", "model_type:checkpoints", "unit-tests", scope]
|
||||
asset_factory("dn_a.safetensors", tags, {}, make_asset_bytes("dn_a", 700))
|
||||
|
|
@ -371,8 +371,7 @@ def test_list_assets_hash_filter_no_match(http, api_base, asset_factory, make_as
|
|||
def test_list_assets_hash_filter_normalizes_case_and_whitespace(
|
||||
http, api_base, asset_factory, make_asset_bytes
|
||||
):
|
||||
"""`hash` is trimmed and lowercased before matching, so an upper-cased,
|
||||
space-padded value still matches the stored lowercase hash."""
|
||||
"""An upper-cased, space-padded `hash` still matches the stored hash."""
|
||||
scope = f"lf-hashnorm-{uuid.uuid4().hex[:6]}"
|
||||
tags = ["models", "model_type:checkpoints", "unit-tests", scope]
|
||||
a = asset_factory("hnorm_a.safetensors", tags, {}, make_asset_bytes("hnorm_a", 1024))
|
||||
|
|
@ -396,8 +395,8 @@ def test_list_assets_hash_filter_normalizes_case_and_whitespace(
|
|||
def test_list_assets_hash_filter_empty_returns_empty_page(
|
||||
http, api_base, asset_factory, make_asset_bytes
|
||||
):
|
||||
"""An explicitly-supplied but empty `hash` (`?hash=`) is an exact-match miss
|
||||
and returns an empty page, rather than silently disabling the filter."""
|
||||
"""An empty `hash` matches nothing and returns an empty page, rather than
|
||||
disabling the filter."""
|
||||
scope = f"lf-hashempty-{uuid.uuid4().hex[:6]}"
|
||||
tags = ["models", "model_type:checkpoints", "unit-tests", scope]
|
||||
asset_factory("he_a.safetensors", tags, {}, make_asset_bytes("he_a", 800))
|
||||
|
|
@ -414,8 +413,7 @@ def test_list_assets_hash_filter_empty_returns_empty_page(
|
|||
|
||||
|
||||
def test_list_assets_include_public_accepted(http, api_base, asset_factory, make_asset_bytes):
|
||||
"""`include_public` is accepted for contract parity; core results are always
|
||||
the caller's own assets regardless of its value (the param is inert)."""
|
||||
"""`include_public` is accepted and does not change which assets come back."""
|
||||
scope = f"lf-incpub-{uuid.uuid4().hex[:6]}"
|
||||
tags = ["models", "model_type:checkpoints", "unit-tests", scope]
|
||||
a = asset_factory("ip_a.safetensors", tags, {}, make_asset_bytes("ip_a", 900))
|
||||
|
|
@ -429,7 +427,7 @@ def test_list_assets_include_public_accepted(http, api_base, asset_factory, make
|
|||
body = r.json()
|
||||
assert r.status_code == 200, body
|
||||
names = [x["name"] for x in body["assets"]]
|
||||
assert a["name"] in names, f"caller's own asset must be returned (include_public={value})"
|
||||
assert a["name"] in names, f"asset must be returned (include_public={value})"
|
||||
|
||||
|
||||
def test_list_assets_name_contains_literal_underscore(
|
||||
|
|
|
|||
Loading…
Reference in New Issue