diff --git a/fastapi_cdn_host/client.py b/fastapi_cdn_host/client.py index 5c7eb3b..3b646a4 100644 --- a/fastapi_cdn_host/client.py +++ b/fastapi_cdn_host/client.py @@ -2,7 +2,9 @@ import inspect import logging import math +import os import re +import sys from dataclasses import dataclass from enum import Enum from pathlib import Path @@ -236,6 +238,7 @@ class CdnHostBuilder: swagger_ui_full_version = "5.17.14" swagger_files = {"css": "swagger-ui.css", "js": "swagger-ui-bundle.js"} redoc_file = "redoc.standalone.js" + default_cache_file = "~/.cache/fastapi-cdn-host/urls.txt" def __init__( self, app=None, docs_cdn_host=None, favicon_url=None, cache=None @@ -281,14 +284,26 @@ def run(self) -> AssetUrl: return urls return self._cache_wrap(self.run_async)(self.sniff_the_fastest, favicon) + def get_cache_file(self) -> Tuple[bool, Path]: + file = Path(os.path.expanduser(self.default_cache_file)) + try: + exists = file.exists() + except PermissionError: + tmp_dir = Path("/tmp") # nosec:B108 + if sys.platform == "win32": + tmp_dir = Path(os.getenv("temp", ".")) # NOQA:SIM112 + file = tmp_dir / self.default_cache_file.replace("~/", "") + exists = file.exists() + return exists, file + def _cache_wrap(self, func: Callable) -> Callable[..., AssetUrl]: if not self._cache: return func @functools.wraps(func) def wrapper(*args, **kw): - file = Path.home() / ".cache" / "fastapi-cdn-host" / "urls.txt" - if file.exists(): + already_cached, file = self.get_cache_file() + if already_cached: lines = file.read_text("utf8").splitlines() if len(lines) == 3: css = js = redoc = "" diff --git a/tests/cache_is_true/test_cache_true.py b/tests/cache_is_true/test_cache_true.py index d61a225..014a089 100644 --- a/tests/cache_is_true/test_cache_true.py +++ b/tests/cache_is_true/test_cache_true.py @@ -1,6 +1,8 @@ # mypy: no-disallow-untyped-decorators import importlib +import os import re +import sys from pathlib import Path import main @@ -73,3 +75,21 @@ async def test_docs(client: AsyncClient): # nosec urls = AssetUrl(css=lines[0], js=lines[1], redoc=lines[2]) importlib.reload(main) await _run_test(cache_file, urls, client) + + +def test_cache_file(mocker, tmp_path): + file = tmp_path / "foo" / "a.txt" + file.parent.mkdir() + file.touch() + assert os.path.exists(str(file)) + file.parent.chmod(0) + with pytest.raises(PermissionError): + file.exists() + mocker.patch("os.path.expanduser", return_value=str(file)) + _, cache_file = CdnHostBuilder().get_cache_file() + if sys.platform == "win32": + temp_directory_env_name = "temp" + temp_dir = Path(os.getenv(temp_directory_env_name, ".")) + assert cache_file == temp_dir / ".cache/fastapi-cdn-host/urls.txt" + else: + assert cache_file.as_posix() == "/tmp/.cache/fastapi-cdn-host/urls.txt"