refactor: rename functions to verb-based naming convention

Rename functions across app/assets/ to follow verb-based naming:
- is_scalar → check_is_scalar
- project_kv → expand_metadata_to_rows
- _visible_owner_clause → _build_visible_owner_clause
- _chunk_rows → _iter_row_chunks
- _at_least_one → _validate_at_least_one_field
- _tags_norm → _normalize_tags_field
- _ser_dt → _serialize_datetime
- _ser_updated → _serialize_updated_at
- _error_response → _build_error_response
- _validation_error_response → _build_validation_error_response
- file_sender → stream_file_chunks
- seed_assets_endpoint → seed_assets
- utcnow → get_utc_now
- _safe_sort_field → _validate_sort_field
- _safe_filename → _sanitize_filename
- fast_asset_file_check → check_asset_file_fast
- prefixes_for_root → get_prefixes_for_root
- blake3_hash → compute_blake3_hash
- blake3_hash_async → compute_blake3_hash_async
- _is_within → _check_is_within
- _rel → _compute_relative

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Luke Mino-Altherr
2026-02-03 13:58:14 -08:00
parent 11ca1995a3
commit 481a2fa263
19 changed files with 132 additions and 132 deletions

View File

@@ -20,7 +20,7 @@ from sqlalchemy import (
)
from sqlalchemy.orm import Mapped, foreign, mapped_column, relationship
from app.assets.helpers import utcnow
from app.assets.helpers import get_utc_now
from app.database.models import to_dict, Base
@@ -32,7 +32,7 @@ class Asset(Base):
size_bytes: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
mime_type: Mapped[str | None] = mapped_column(String(255))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=False), nullable=False, default=utcnow
DateTime(timezone=False), nullable=False, default=get_utc_now
)
infos: Mapped[list[AssetInfo]] = relationship(
@@ -105,9 +105,9 @@ class AssetInfo(Base):
asset_id: Mapped[str] = mapped_column(String(36), ForeignKey("assets.id", ondelete="RESTRICT"), nullable=False)
preview_id: Mapped[str | None] = mapped_column(String(36), ForeignKey("assets.id", ondelete="SET NULL"))
user_metadata: Mapped[dict[str, Any] | None] = mapped_column(JSON(none_as_null=True))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=utcnow)
last_access_time: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=utcnow)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=get_utc_now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=get_utc_now)
last_access_time: Mapped[datetime] = mapped_column(DateTime(timezone=False), nullable=False, default=get_utc_now)
asset: Mapped[Asset] = relationship(
"Asset",
@@ -196,7 +196,7 @@ class AssetInfoTag(Base):
)
origin: Mapped[str] = mapped_column(String(32), nullable=False, default="manual")
added_at: Mapped[datetime] = mapped_column(
DateTime(timezone=False), nullable=False, default=utcnow
DateTime(timezone=False), nullable=False, default=get_utc_now
)
asset_info: Mapped[AssetInfo] = relationship(back_populates="tag_links")

View File

@@ -18,10 +18,10 @@ from sqlalchemy.orm import Session, contains_eager, noload
from app.assets.database.models import (
Asset, AssetInfo, AssetInfoMeta, AssetInfoTag, Tag
)
from app.assets.helpers import escape_like_prefix, normalize_tags, utcnow
from app.assets.helpers import escape_like_prefix, normalize_tags, get_utc_now
def is_scalar(v):
def check_is_scalar(v):
if v is None:
return True
if isinstance(v, bool):
@@ -31,7 +31,7 @@ def is_scalar(v):
return False
def project_kv(key: str, value):
def expand_metadata_to_rows(key: str, value):
"""
Turn a metadata key/value into typed projection rows.
Returns list[dict] with keys:
@@ -49,7 +49,7 @@ def project_kv(key: str, value):
rows.append(_null_row(0))
return rows
if is_scalar(value):
if check_is_scalar(value):
if isinstance(value, bool):
rows.append({"key": key, "ordinal": 0, "val_bool": bool(value)})
elif isinstance(value, (int, float, Decimal)):
@@ -62,7 +62,7 @@ def project_kv(key: str, value):
return rows
if isinstance(value, list):
if all(is_scalar(x) for x in value):
if all(check_is_scalar(x) for x in value):
for i, x in enumerate(value):
if x is None:
rows.append(_null_row(i))
@@ -95,7 +95,7 @@ def _iter_chunks(seq, n: int):
yield seq[i : i + n]
def _visible_owner_clause(owner_id: str) -> sa.sql.ClauseElement:
def _build_visible_owner_clause(owner_id: str) -> sa.sql.ClauseElement:
"""Build owner visibility predicate for reads. Owner-less rows are visible to everyone."""
owner_id = (owner_id or "").strip()
if owner_id == "":
@@ -210,7 +210,7 @@ def insert_asset_info(
preview_id: str | None = None,
) -> AssetInfo | None:
"""Insert a new AssetInfo. Returns None if unique constraint violated."""
now = utcnow()
now = get_utc_now()
try:
with session.begin_nested():
info = AssetInfo(
@@ -267,7 +267,7 @@ def update_asset_info_timestamps(
preview_id: str | None = None,
) -> None:
"""Update timestamps and optionally preview_id on existing AssetInfo."""
now = utcnow()
now = get_utc_now()
if preview_id and asset_info.preview_id != preview_id:
asset_info.preview_id = preview_id
asset_info.updated_at = now
@@ -292,7 +292,7 @@ def list_asset_infos_page(
select(AssetInfo)
.join(Asset, Asset.id == AssetInfo.asset_id)
.options(contains_eager(AssetInfo.asset), noload(AssetInfo.tags))
.where(_visible_owner_clause(owner_id))
.where(_build_visible_owner_clause(owner_id))
)
if name_contains:
@@ -320,7 +320,7 @@ def list_asset_infos_page(
select(sa.func.count())
.select_from(AssetInfo)
.join(Asset, Asset.id == AssetInfo.asset_id)
.where(_visible_owner_clause(owner_id))
.where(_build_visible_owner_clause(owner_id))
)
if name_contains:
escaped, esc = escape_like_prefix(name_contains)
@@ -359,7 +359,7 @@ def fetch_asset_info_asset_and_tags(
.join(Tag, Tag.name == AssetInfoTag.tag_name, isouter=True)
.where(
AssetInfo.id == asset_info_id,
_visible_owner_clause(owner_id),
_build_visible_owner_clause(owner_id),
)
.options(noload(AssetInfo.tags))
.order_by(Tag.name.asc())
@@ -389,7 +389,7 @@ def fetch_asset_info_and_asset(
.join(Asset, Asset.id == AssetInfo.asset_id)
.where(
AssetInfo.id == asset_info_id,
_visible_owner_clause(owner_id),
_build_visible_owner_clause(owner_id),
)
.limit(1)
.options(noload(AssetInfo.tags))
@@ -407,7 +407,7 @@ def touch_asset_info_by_id(
ts: datetime | None = None,
only_if_newer: bool = True,
) -> None:
ts = ts or utcnow()
ts = ts or get_utc_now()
stmt = sa.update(AssetInfo).where(AssetInfo.id == asset_info_id)
if only_if_newer:
stmt = stmt.where(
@@ -426,7 +426,7 @@ def replace_asset_info_metadata_projection(
raise ValueError(f"AssetInfo {asset_info_id} not found")
info.user_metadata = user_metadata or {}
info.updated_at = utcnow()
info.updated_at = get_utc_now()
session.flush()
session.execute(delete(AssetInfoMeta).where(AssetInfoMeta.asset_info_id == asset_info_id))
@@ -437,7 +437,7 @@ def replace_asset_info_metadata_projection(
rows: list[AssetInfoMeta] = []
for k, v in user_metadata.items():
for r in project_kv(k, v):
for r in expand_metadata_to_rows(k, v):
rows.append(
AssetInfoMeta(
asset_info_id=asset_info_id,
@@ -461,7 +461,7 @@ def delete_asset_info_by_id(
) -> bool:
stmt = sa.delete(AssetInfo).where(
AssetInfo.id == asset_info_id,
_visible_owner_clause(owner_id),
_build_visible_owner_clause(owner_id),
)
return int((session.execute(stmt)).rowcount or 0) > 0
@@ -483,7 +483,7 @@ def set_asset_info_preview(
raise ValueError(f"Preview Asset {preview_asset_id} not found")
info.preview_id = preview_asset_id
info.updated_at = utcnow()
info.updated_at = get_utc_now()
session.flush()

View File

@@ -7,7 +7,7 @@ from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from app.assets.database.models import AssetInfo, AssetInfoMeta, AssetInfoTag, Tag
from app.assets.helpers import escape_like_prefix, normalize_tags, utcnow
from app.assets.helpers import escape_like_prefix, normalize_tags, get_utc_now
MAX_BIND_PARAMS = 800
@@ -16,7 +16,7 @@ def _rows_per_stmt(cols: int) -> int:
return max(1, MAX_BIND_PARAMS // max(1, cols))
def _chunk_rows(rows: list[dict], cols_per_row: int) -> Iterable[list[dict]]:
def _iter_row_chunks(rows: list[dict], cols_per_row: int) -> Iterable[list[dict]]:
if not rows:
return []
rows_per_stmt = max(1, MAX_BIND_PARAMS // max(1, cols_per_row))
@@ -24,7 +24,7 @@ def _chunk_rows(rows: list[dict], cols_per_row: int) -> Iterable[list[dict]]:
yield rows[i : i + rows_per_stmt]
def _visible_owner_clause(owner_id: str) -> sa.sql.ClauseElement:
def _build_visible_owner_clause(owner_id: str) -> sa.sql.ClauseElement:
"""Build owner visibility predicate for reads. Owner-less rows are visible to everyone."""
owner_id = (owner_id or "").strip()
if owner_id == "":
@@ -75,7 +75,7 @@ def set_asset_info_tags(
if to_add:
ensure_tags_exist(session, to_add, tag_type="user")
session.add_all([
AssetInfoTag(asset_info_id=asset_info_id, tag_name=t, origin=origin, added_at=utcnow())
AssetInfoTag(asset_info_id=asset_info_id, tag_name=t, origin=origin, added_at=get_utc_now())
for t in to_add
])
session.flush()
@@ -132,7 +132,7 @@ def add_tags_to_asset_info(
asset_info_id=asset_info_id,
tag_name=t,
origin=origin,
added_at=utcnow(),
added_at=get_utc_now(),
)
for t in to_add
]
@@ -199,7 +199,7 @@ def add_missing_tag_for_asset_id(
AssetInfo.id.label("asset_info_id"),
sa.literal("missing").label("tag_name"),
sa.literal(origin).label("origin"),
sa.literal(utcnow()).label("added_at"),
sa.literal(get_utc_now()).label("added_at"),
)
.where(AssetInfo.asset_id == asset_id)
.where(
@@ -246,7 +246,7 @@ def list_tags_with_usage(
)
.select_from(AssetInfoTag)
.join(AssetInfo, AssetInfo.id == AssetInfoTag.asset_info_id)
.where(_visible_owner_clause(owner_id))
.where(_build_visible_owner_clause(owner_id))
.group_by(AssetInfoTag.tag_name)
.subquery()
)
@@ -305,12 +305,12 @@ def bulk_insert_tags_and_meta(
ins_tags = sqlite.insert(AssetInfoTag).on_conflict_do_nothing(
index_elements=[AssetInfoTag.asset_info_id, AssetInfoTag.tag_name]
)
for chunk in _chunk_rows(tag_rows, cols_per_row=4):
for chunk in _iter_row_chunks(tag_rows, cols_per_row=4):
session.execute(ins_tags, chunk)
if meta_rows:
ins_meta = sqlite.insert(AssetInfoMeta).on_conflict_do_nothing(
index_elements=[AssetInfoMeta.asset_info_id, AssetInfoMeta.key, AssetInfoMeta.ordinal]
)
for chunk in _chunk_rows(meta_rows, cols_per_row=7):
for chunk in _iter_row_chunks(meta_rows, cols_per_row=7):
session.execute(ins_meta, chunk)