Skip to content

Commit 855fbb9

Browse files
bk86aclaude
andcommitted
chore: cut v0.19.0
Bumps __version__ to 0.19.0 and folds the [Unreleased] CHANGELOG block into a dated [0.19.0] release. Adds entries for the two diagnostic-PR landings since the prior cut: /admin/memory endpoint (#75) and the follow-up offload of its gc walk to a thread (#76). Other changes already in [Unreleased] from the prior week: - / root endpoint - persistent-volume support (entrypoint chown + gosu) - provider-agnostic deployment scaffolding (compose.yaml + Makefile) - periodic refresh of tercet_missing_codes.csv (#44) - 85 new postal-code estimates from postal_code_monitor.py (#74) - uvicorn --proxy-headers --forwarded-allow-ips '*' in CMD - entrypoint safe under non-root --user - multi-worker performance re-baseline - estimates_refresh serialisation lock - perf_test run_warm fix - previously-stale __version__ catch-up Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 351b1de commit 855fbb9

2 files changed

Lines changed: 5 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
66

77
## [Unreleased]
88

9+
## [0.19.0] - 2026-05-03
10+
911
### Added
1012

1113
- **`/` root endpoint** returns service metadata and pointers to `/openapi.json`, `/docs`, `/redoc`, `/health`, and example `/lookup` and `/pattern` URLs. Replaces the previous `{"detail":"Not Found"}` response on the bare hostname. Marked `include_in_schema=False` so it doesn't clutter the OpenAPI document.
1214
- **Persistent-volume support** via a new `docker-entrypoint.sh`: container starts as root, `chown appuser:appuser /app/data` (idempotent — no-op on warm starts), then `exec gosu appuser "$@"` to drop privileges before uvicorn starts. `Dockerfile` installs `gosu` and replaces `USER appuser` with `ENTRYPOINT`. Lets a freshly-provisioned platform persistent volume (initially root-owned) be mounted at `/app/data` without breaking the SQLite cache build. Cold-start cache survives pod recreates and redeploys; subsequent restarts skip the GISCO TERCET re-download until the configured TTL expires.
1315
- **Provider-agnostic deployment**: new `compose.yaml` at the repo root demonstrates the canonical multi-worker production pattern (api + redis sidecar + persistent volume + multi-worker env vars) in a way that runs unmodified anywhere Docker Compose is supported and translates 1:1 to Kubernetes pods, ECS task definitions, or any orchestrator with multi-container semantics. New `compose-up`/`compose-down`/`compose-logs` Makefile targets. README "Docker deployment" section rewritten to point at it and to call out the swap-out points for switching providers.
1416
- **Periodic refresh of `tercet_missing_codes.csv`** (#44): when `PC2NUTS_ESTIMATES_REFRESH_URL` is set, a per-worker asyncio task fetches the URL on every `PC2NUTS_ESTIMATES_REFRESH_INTERVAL_SECONDS` tick (default 24 h), parses the body, and full-replaces the in-memory estimates table if the content has changed and passes a 50 %-of-current sanity guard. Workers also do a synchronous bootstrap fetch before reporting ready, so a fresh pod immediately reflects upstream rather than waiting up to one interval. New `POST /admin/refresh-estimates` endpoint (trusted-token auth) lets operators force a refresh without waiting. New `/health` field `estimates_refresh_stale: bool | None`. Defaults preserve the current single-source-of-truth behaviour from the bundled `tercet_missing_codes.csv`.
17+
- **`/admin/memory` diagnostic endpoint** (#75, #76): operator-only `GET` (trusted-token auth, `include_in_schema=False`) returning module-scoped dict sizes (`_lookup`, `_estimates`, `_prefix_index`, slowapi `_storage.*`, `auth._db_tokens`, ...), `/proc/self/status` counters (`VmRSS` / `VmHWM` / `RssAnon` / `RssFile` / `Threads`), file-descriptor count, asyncio task count + sample, and a top-30 `gc.get_objects()` type histogram. The histogram walk runs in `asyncio.to_thread` so the GIL releases during the pure-Python iteration and other coroutines on the worker can interleave; `gc.collect()` is intentionally omitted because on a multi-GB heap it costs seconds and holds the GIL throughout. Built for in-process leak investigations — diff two snapshots to localise the growing class.
18+
- **85 new postal-code estimates** (#74) added to `tercet_missing_codes.csv` by the automated `postal_code_monitor.py`, covering codes that were either absent from TERCET (404) or only had approximate matches under the runtime estimator. Codes derived from neighbouring postal-code lookups via the API.
1519

1620
### Changed
1721

app/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.18.0"
1+
__version__ = "0.19.0"

0 commit comments

Comments
 (0)