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]