withcache 0.11.1__tar.gz → 0.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {withcache-0.11.1 → withcache-0.13.0}/PKG-INFO +1 -1
  2. {withcache-0.11.1 → withcache-0.13.0}/shim/build.zig.zon +1 -1
  3. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/__init__.py +1 -1
  4. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_api.py +22 -1
  5. withcache-0.13.0/src/withcache/_app.py +1018 -0
  6. withcache-0.13.0/src/withcache/_events_log.py +277 -0
  7. withcache-0.13.0/src/withcache/_table_state.py +152 -0
  8. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_templates/ui/_layout.html +7 -11
  9. withcache-0.13.0/src/withcache/_templates/ui/_table_macros.html +126 -0
  10. withcache-0.13.0/src/withcache/_templates/ui/catalog.html +195 -0
  11. withcache-0.13.0/src/withcache/_templates/ui/dashboard.html +160 -0
  12. withcache-0.13.0/src/withcache/_templates/ui/events.html +125 -0
  13. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_templates/ui/misses.html +14 -11
  14. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_templates/ui/settings.html +73 -36
  15. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/server.py +86 -7
  16. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_admin_forms.py +113 -68
  17. withcache-0.13.0/tests/test_fastapi_events.py +205 -0
  18. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_scaffold.py +11 -11
  19. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_ui_pages.py +49 -28
  20. withcache-0.11.1/src/withcache/_app.py +0 -644
  21. withcache-0.11.1/src/withcache/_templates/ui/cached.html +0 -73
  22. withcache-0.11.1/src/withcache/_templates/ui/catalog.html +0 -275
  23. withcache-0.11.1/src/withcache/_templates/ui/downloads.html +0 -102
  24. {withcache-0.11.1 → withcache-0.13.0}/.gitignore +0 -0
  25. {withcache-0.11.1 → withcache-0.13.0}/LICENSE +0 -0
  26. {withcache-0.11.1 → withcache-0.13.0}/README.md +0 -0
  27. {withcache-0.11.1 → withcache-0.13.0}/deploy/Containerfile +0 -0
  28. {withcache-0.11.1 → withcache-0.13.0}/deploy/compose.local-build.yml +0 -0
  29. {withcache-0.11.1 → withcache-0.13.0}/deploy/compose.yml +0 -0
  30. {withcache-0.11.1 → withcache-0.13.0}/deploy/envvars.example +0 -0
  31. {withcache-0.11.1 → withcache-0.13.0}/hatch_build.py +0 -0
  32. {withcache-0.11.1 → withcache-0.13.0}/pyproject.toml +0 -0
  33. {withcache-0.11.1 → withcache-0.13.0}/shim/build.zig +0 -0
  34. {withcache-0.11.1 → withcache-0.13.0}/shim/shim.zig +0 -0
  35. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_settings_store.py +0 -0
  36. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_shim.py +0 -0
  37. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/_templates/ui/login.html +0 -0
  38. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/client.py +0 -0
  39. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/curlwithcache.py +0 -0
  40. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/oras.py +0 -0
  41. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/static/bootstrap-icons.min.css +0 -0
  42. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/static/bootstrap.min.css +0 -0
  43. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/static/fonts/bootstrap-icons.woff +0 -0
  44. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/static/fonts/bootstrap-icons.woff2 +0 -0
  45. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/static/htmx.min.js +0 -0
  46. {withcache-0.11.1 → withcache-0.13.0}/src/withcache/wgetwithcache.py +0 -0
  47. {withcache-0.11.1 → withcache-0.13.0}/tests/test_differential.py +0 -0
  48. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_blob.py +0 -0
  49. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_catalog_api.py +0 -0
  50. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_settings_persistence.py +0 -0
  51. {withcache-0.11.1 → withcache-0.13.0}/tests/test_fastapi_uvicorn_smoke.py +0 -0
  52. {withcache-0.11.1 → withcache-0.13.0}/tests/test_oras.py +0 -0
  53. {withcache-0.11.1 → withcache-0.13.0}/tests/test_withcache.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: withcache
3
- Version: 0.11.1
3
+ Version: 0.13.0
4
4
  Summary: Operator-curated, URL-keyed artifact cache for a small lab (CUDA/ROCm/DOCA/firmware)
5
5
  Project-URL: Homepage, https://github.com/safl/withcache
6
6
  Author-email: "Simon A. F. Lund" <safl@safl.dk>
@@ -2,7 +2,7 @@
2
2
  .name = .withcache_shim,
3
3
  // Zig requires a literal here; keep it in lockstep with the project's
4
4
  // single source (src/withcache/__init__.py) via `make bump` / `make version-check`.
5
- .version = "0.11.1",
5
+ .version = "0.13.0",
6
6
  .fingerprint = 0xd7d96c5ed212ccaa,
7
7
  .minimum_zig_version = "0.16.0",
8
8
  .paths = .{
@@ -22,6 +22,6 @@ inherit the framework floor.
22
22
  from . import oras
23
23
  from .client import blob_url, cache_base, is_cached, serve_url
24
24
 
25
- __version__ = "0.11.1"
25
+ __version__ = "0.13.0"
26
26
 
27
27
  __all__ = ["__version__", "blob_url", "cache_base", "is_cached", "oras", "serve_url"]
@@ -30,6 +30,7 @@ Downloads page shows in-flight transfers as they run.
30
30
  from __future__ import annotations
31
31
 
32
32
  import base64
33
+ import contextlib
33
34
  import urllib.parse
34
35
  from collections.abc import Iterator
35
36
  from typing import Any
@@ -88,7 +89,27 @@ def _serve_blob(
88
89
  row = None
89
90
 
90
91
  if row is None:
91
- store.record_miss(url)
92
+ fresh = store.record_miss(url)
93
+ if fresh:
94
+ # First miss for this URL: emit an audit event so the
95
+ # operator sees it on /ui/events. Subsequent misses for
96
+ # the same URL bump the counter without re-emitting.
97
+ from . import _events_log
98
+
99
+ with contextlib.suppress(Exception):
100
+ with store.conn() as ev_conn:
101
+ _events_log.record(
102
+ ev_conn,
103
+ kind="blob.miss.recorded",
104
+ summary=f"First cache miss for {url}",
105
+ subject_kind="blob",
106
+ subject_id=url,
107
+ actor="client",
108
+ source_ip=_events_log.normalize_ip(
109
+ request.client.host if request.client else None
110
+ ),
111
+ )
112
+ ev_conn.commit()
92
113
  return PlainTextResponse(
93
114
  "cache miss: this URL hasn't been downloaded yet. "
94
115
  "Pick the matching catalog entry on /ui/catalog and hit Download.\n",