from __future__ import annotations from quart import current_app DEFAULT_BROWSER_MAX_AGE = 86400 DEFAULT_EDGE_MAX_AGE = 1800 def file_cache(): """The app's FileCache, or None when caching is not configured.""" return getattr(current_app, 'file_cache', None) def browser_max_age() -> int: cache = file_cache() return DEFAULT_BROWSER_MAX_AGE if cache is None else cache.blob_max_age def edge_max_age() -> int: cache = file_cache() return DEFAULT_EDGE_MAX_AGE if cache is None else cache.edge_max_age async def load_file(file_id: str): async def loader(): return await current_app.convex.get_file(file_id=file_id) cache = file_cache() if cache is None: return await loader() return await cache.get_metadata(file_id, loader) async def load_blob(storage_key: str) -> bytes: async def loader() -> bytes: payload = await current_app.convex.get_from_storage(storage_key) return payload.getvalue() if hasattr(payload, 'getvalue') else bytes(payload) cache = file_cache() if cache is None: return await loader() return await cache.get_blob(storage_key, loader) async def drop_file_cache(file_id: str) -> None: """Invalidate metadata after a mutation; blobs are immutable and expire on TTL.""" cache = file_cache() if cache is not None: await cache.invalidate(file_id)