Repository navigation
PER-16680: log through an SDK logger that applies the log settings - #163
EliMoshkovich wants to merge 2 commits into
Conversation
Ported to main from #137 (Zeev Manilovich), which is stacked on the release-CI draft #136; this carries only #137's own changes. - The client no longer logs its config on creation; it logs the PDP and API URL. - permit.utils.sdk_logger applies log.level and log.label to the SDK's records without touching the application's loguru sinks, and replaces every client's API key with [REDACTED] in what the SDK logs and in PDP error bodies. - PermitConfig.token is repr=False. - ruff bans logging straight to loguru inside the package. - README: what each log option does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dependency Security AuditScanned: pyproject.toml dependencies + dev group, resolved at Python 3.10 (the current resolution, and the lowest versions the published specs permit under each pydantic major) ❌ 6 fixable HIGH/CRITICAL advisories -- blocking this build.
Advisory detailsCRITICAL -- GHSA-hq85-5cpj-mr62 ( Found by: trivy:dev-ceiling HIGH -- CVE-2026-111064 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 HIGH -- CVE-2026-111066 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 HIGH -- GHSA-2g87-pp6c-29x5 ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2, trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 HIGH -- CVE-2026-114605 ( Found by: trivy:dev-ceiling, trivy:runtime-ceiling, trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 HIGH -- CVE-2026-112940 ( Found by: trivy:dev-ceiling MEDIUM -- CVE-2026-111063 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 MEDIUM -- CVE-2026-111065 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 MEDIUM -- CVE-2026-111748 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 MEDIUM -- CVE-2026-111750 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 MEDIUM -- CVE-2026-112906 ( Found by: trivy:dev-ceiling MEDIUM -- CVE-2026-112914 ( Found by: trivy:dev-ceiling MEDIUM -- CVE-2026-112937 ( Found by: trivy:dev-ceiling MEDIUM -- CVE-2026-104843 ( Found by: trivy:dev-ceiling MEDIUM -- CVE-2026-102598 ( Found by: trivy:dev-ceiling LOW -- CVE-2026-111749 ( Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2 LOW -- CVE-2026-112907 ( Found by: trivy:dev-ceiling LOW -- CVE-2026-112913 ( Found by: trivy:dev-ceiling UNKNOWN -- CVE-2026-111063 (GHSA-494j-54xm-rwp3) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111064 (GHSA-5wr8-gcqf-gqf3) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111065 (GHSA-6cjc-53gc-5rqm) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111066 (GHSA-9xw5-w5jj-pvcg) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111748 (GHSA-f9xw-jh8m-3mwq) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111749 (GHSA-gx76-c99x-2c96) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-111750 (GHSA-pqxq-w44r-73xw) ( Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-114605 (GHSA-45c3-73f7-pv4m) ( Found by: pip-audit:dev-ceiling, pip-audit:runtime-ceiling, pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2 UNKNOWN -- CVE-2026-112906 (GHSA-2g95-wg33-c5x2) ( Found by: pip-audit:dev-ceiling UNKNOWN -- CVE-2026-112907 (GHSA-567q-5qvw-pf92) ( Found by: pip-audit:dev-ceiling UNKNOWN -- CVE-2026-112913 (GHSA-9vhv-jxww-xfm5) ( Found by: pip-audit:dev-ceiling UNKNOWN -- CVE-2026-112914 (GHSA-crv4-6mhj-j5jh) ( Found by: pip-audit:dev-ceiling UNKNOWN -- CVE-2026-112937 (GHSA-jqc4-5cvw-7w85) ( Found by: pip-audit:dev-ceiling UNKNOWN -- CVE-2026-112940 (GHSA-v4x8-3wr5-3wq8) ( Found by: pip-audit:dev-ceiling UNKNOWN -- PYSEC-2026-4305 (CVE-2026-104843, GHSA-2cv4-cqwr-gwf7) ( Found by: pip-audit:dev-ceiling UNKNOWN -- PYSEC-2026-4321 (GHSA-hq85-5cpj-mr62) ( Found by: pip-audit:dev-ceiling UNKNOWN -- PYSEC-2026-4312 (CVE-2026-102598, GHSA-g6x2-hccm-hh4m) ( Found by: pip-audit:dev-ceiling How to fixRaise the affected lower bound in This audit resolves without the 7-day publish-age cooldown ( An advisory with no fix available does not block the build -- it is reported here so it can be tracked, but no version bump can resolve it. Suppression files are deliberately not honoured: the scan runs with |
… info, wait_for_sync - handle_api_error scrubs the registered keys from the body it puts in an exception, text or JSON, so the REST API and the PDP's local API raise without them, as the enforcer already did. - The start-up line logs api_url and pdp without a user name or password. - wait_for_sync builds a client of the same class again, so a subclass's own setup runs, and keeps the process's log settings through the keep_log_settings context variable. - A secret shorter than 12 characters is not redacted, so a short test token doesn't mangle the SDK's text. - log.level takes a loguru severity number and surrounding whitespace; an unknown level is warned about once per process. - The SDK's enable/disable switch changes under a lock. - Drop sync.Permit.__init__, which only called super(). - README and docstrings match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Linear: PER-16680
This ports #137 (Zeev) to
main, with review follow-ups on top. #137 is stacked on the release-CI draft #136; this PR carries only #137's own changes, so the logging fix can ship in a patch release without that stack.Changes
api_urlandpdpat debug, without any user name or password in them.permit.utils.sdk_loggeris what the SDK logs through:log.levelandlog.labelto the SDK's own records, without adding a sink or changing the application's loguru setup.leveltakes a name in any case, or a loguru severity number. An unknown one is warned about once per process.[REDACTED]in the records the SDK logs and in the error bodies of the exceptions it raises: the enforcer's, and the REST and PDP local API errors fromhandle_api_error, text or JSON.PermitConfig.tokenisrepr=False.wait_for_sync()builds a client of the same class again, so a subclass's own setup runs. Thekeep_log_settingscontext variable keeps the process's log settings unchanged while it does.loguru.loggerdirectly inside the package.sync.Permit.__init__, which only calledsuper().Behaviour change
log.levelandlog.labelused to be ignored. Withlog={"enable": True}and nothing else, the defaults now apply:info).[Permit].Set
level="debug"orlabel=""to keep the old output.Left as is
Tests
tests/test_fix_logging.py: 62 tests, #137's 53 plus 9 for the follow-ups:wait_for_syncRan locally:
uv run pyteston the offline suites (tests/test_fix_*.py,test_offline_regressions.py,test_sync_client.py,test_typing_surface.py), pydantic v2: 365 passed, 3 skipped. 2 errors need a livePDP_API_KEY.test_sync_client.pyandtest_typing_surface.py: 362 passed, 3 skipped.pre-commiton the changed files: ruff, mypy and typos pass.🤖 Generated with Claude Code