This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git


The following commit(s) were added to refs/heads/main by this push:
     new 56621dd  Try the admin cache file in synchronous contexts too
56621dd is described below

commit 56621dd18568f685e595f4c1c35849413a5f4b7c
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Jan 27 15:50:18 2026 +0000

    Try the admin cache file in synchronous contexts too
---
 atr/cache.py             | 70 ++++++++++++++++++++++++++++++++----------------
 tests/unit/test_cache.py |  8 +++---
 2 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/atr/cache.py b/atr/cache.py
index 19d572e..f652a02 100644
--- a/atr/cache.py
+++ b/atr/cache.py
@@ -39,31 +39,21 @@ class AdminsCache(schema.Strict):
 
 
 def admins_get() -> frozenset[str]:
-    app = asfquart.APP
-    return app.extensions.get("admins", frozenset())
+    if asfquart.APP is not None:
+        return asfquart.APP.extensions.get("admins", frozenset())
+    cache_data = _admins_read_from_file()
+    if cache_data is None:
+        return frozenset()
+    return cache_data.admins
 
 
 async def admins_get_async() -> frozenset[str]:
-    try:
-        return admins_get()
-    except (AttributeError, RuntimeError):
-        cache_data = await admins_read_from_file()
-        if cache_data is None:
-            return frozenset()
-        return cache_data.admins
-
-
-async def admins_read_from_file() -> AdminsCache | None:
-    cache_path = _admins_path()
-    if not cache_path.exists():
-        return None
-    try:
-        async with aiofiles.open(cache_path) as f:
-            raw_data = await f.read()
-        return AdminsCache.model_validate_json(raw_data)
-    except (pydantic.ValidationError, OSError) as e:
-        log.warning(f"Failed to read admin users cache: {e}")
-        return None
+    if asfquart.APP is not None:
+        return asfquart.APP.extensions.get("admins", frozenset())
+    cache_data = await _admins_read_from_file_async()
+    if cache_data is None:
+        return frozenset()
+    return cache_data.admins
 
 
 async def admins_refresh_loop() -> None:
@@ -87,7 +77,7 @@ async def admins_save_to_file(admins: frozenset[str]) -> None:
 
 
 async def admins_startup_load() -> None:
-    cache_data = await admins_read_from_file()
+    cache_data = await _admins_read_from_file_async()
     if cache_data is not None:
         _admins_update_app_extensions(cache_data.admins)
         log.info(f"Loaded {len(cache_data.admins)} admin users from cache 
(refreshed: {cache_data.refreshed})")
@@ -106,6 +96,40 @@ def _admins_path() -> pathlib.Path:
     return pathlib.Path(config.get().STATE_DIR) / "cache" / "admins.json"
 
 
+def _admins_read_from_file() -> AdminsCache | None:
+    cache_path = _admins_path()
+    if not cache_path.exists():
+        return None
+    try:
+        with open(cache_path) as f:
+            raw_data = f.read()
+    except OSError as e:
+        log.warning(f"Failed to read admin users cache: {e}")
+        return None
+    try:
+        return AdminsCache.model_validate_json(raw_data)
+    except pydantic.ValidationError as e:
+        log.warning(f"Failed to read admin users cache: {e}")
+        return None
+
+
+async def _admins_read_from_file_async() -> AdminsCache | None:
+    cache_path = _admins_path()
+    if not cache_path.exists():
+        return None
+    try:
+        async with aiofiles.open(cache_path) as f:
+            raw_data = await f.read()
+    except OSError as e:
+        log.warning(f"Failed to read admin users cache: {e}")
+        return None
+    try:
+        return AdminsCache.model_validate_json(raw_data)
+    except pydantic.ValidationError as e:
+        log.warning(f"Failed to read admin users cache: {e}")
+        return None
+
+
 def _admins_update_app_extensions(admins: frozenset[str]) -> None:
     app = asfquart.APP
     app.extensions["admins"] = admins
diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py
index dec2adc..9990c8b 100644
--- a/tests/unit/test_cache.py
+++ b/tests/unit/test_cache.py
@@ -131,7 +131,7 @@ async def 
test_admins_read_from_file_returns_none_for_invalid_json(state_dir: pa
     cache_path = state_dir / "cache" / "admins.json"
     cache_path.parent.mkdir(parents=True)
     cache_path.write_text("not valid json {{{")
-    result = await cache.admins_read_from_file()
+    result = await cache._admins_read_from_file_async()
     assert result is None
 
 
@@ -140,13 +140,13 @@ async def 
test_admins_read_from_file_returns_none_for_invalid_schema(state_dir:
     cache_path = state_dir / "cache" / "admins.json"
     cache_path.parent.mkdir(parents=True)
     cache_path.write_text('{"wrong_field": "value"}')
-    result = await cache.admins_read_from_file()
+    result = await cache._admins_read_from_file_async()
     assert result is None
 
 
 @pytest.mark.asyncio
 async def test_admins_read_from_file_returns_none_for_missing(state_dir: 
pathlib.Path):
-    result = await cache.admins_read_from_file()
+    result = await cache._admins_read_from_file_async()
     assert result is None
 
 
@@ -154,7 +154,7 @@ async def 
test_admins_read_from_file_returns_none_for_missing(state_dir: pathlib
 async def test_admins_save_and_read_roundtrip(state_dir: pathlib.Path):
     original_admins = frozenset({"alice", "bob", "charlie"})
     await cache.admins_save_to_file(original_admins)
-    result = await cache.admins_read_from_file()
+    result = await cache._admins_read_from_file_async()
     assert result is not None
     assert result.admins == original_admins
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to