From fab9b71f5d0a08109aa285869704c684b5e03373 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Thu, 15 Jan 2026 21:13:34 -0800 Subject: [PATCH] Finished @ROUTES.head("/api/assets/hash/{hash}") --- app/assets/api/routes.py | 12 ++++++++++++ app/assets/manager.py | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/assets/api/routes.py b/app/assets/api/routes.py index d08eeae5a..e84b2b690 100644 --- a/app/assets/api/routes.py +++ b/app/assets/api/routes.py @@ -29,6 +29,18 @@ def _validation_error_response(code: str, ve: ValidationError) -> web.Response: return _error_response(400, code, "Validation failed.", {"errors": ve.json()}) +@ROUTES.head("/api/assets/hash/{hash}") +async def head_asset_by_hash(request: web.Request) -> web.Response: + hash_str = request.match_info.get("hash", "").strip().lower() + if not hash_str or ":" not in hash_str: + return _error_response(400, "INVALID_HASH", "hash must be like 'blake3:'") + algo, digest = hash_str.split(":", 1) + if algo != "blake3" or not digest or any(c for c in digest if c not in "0123456789abcdef"): + return _error_response(400, "INVALID_HASH", "hash must be like 'blake3:'") + exists = manager.asset_exists(asset_hash=hash_str) + return web.Response(status=200 if exists else 404) + + @ROUTES.get("/api/assets") async def list_assets(request: web.Request) -> web.Response: """ diff --git a/app/assets/manager.py b/app/assets/manager.py index 14449c018..9860a0944 100644 --- a/app/assets/manager.py +++ b/app/assets/manager.py @@ -25,7 +25,10 @@ def _safe_sort_field(requested: str | None) -> str: return "created_at" -def asset_exists(asset_hash: str) -> bool: +def asset_exists(*, asset_hash: str) -> bool: + """ + Check if an asset with a given hash exists in database. + """ with create_session() as session: return asset_exists_by_hash(session, asset_hash=asset_hash)