github domainaware/parsedmarc 10.1.0

19 hours ago

Changes

  • Graceful shutdown on SIGTERM / SIGINT. Previously SIGTERM (sent by systemctl stop, docker stop, and Kubernetes pod termination) killed the process mid-batch, tearing output writes and silently dropping Kafka producer buffers. parsedmarc now sets a shutdown flag that is polled at safe boundaries: the one-shot CLI checks it between batches, and the watcher passes it as config_reloading so the mailbox backend — including the IMAP IDLE loop — returns once the current batch is processed. Either way the current batch and its output writes finish before the process exits. Ctrl-C is a double-tap: the first press is graceful, the second short-circuits to os._exit(130). This requires the config_reloading-aware IMAP IDLE loop from the pinned mailsuite fork; with a stock mailsuite the IDLE watcher cannot be interrupted cleanly. (PR #794)
    • Output clients are now closed on every exit path via atexit plus a trailing close at the end of _main(), fixing a long-standing leak where one-shot CLI runs and graceful shutdowns never flushed Kafka / closed Elasticsearch / S3 / etc. clients.
    • Example systemd unit in docs/source/usage.md now sets KillSignal=SIGTERM and TimeoutStopSec=60 so systemd waits long enough for the watcher to drain (keep it above mailbox_check_timeout).
  • Switch the Kafka client dependency from kafka-python-ng back to kafka-python>=2.3.2 (#795). kafka-python-ng was a fork created while kafka-python was unmaintained; upstream kafka-python is active again, and the now-archived fork is vulnerable to CVE-2026-10142 and CVE-2026-10143, both fixed in kafka-python 2.3.2. Both packages install the same kafka module, so if you are upgrading an existing environment in place with pip, run pip uninstall kafka-python-ng before upgrading parsedmarc so the two distributions don't conflict with each other's files.
    • parsedmarc is compatible with both kafka-python 2.3.2+ and 3.x: kafka-python 3.0 removed the NoBrokersAvailable exception (a failed bootstrap now raises KafkaTimeoutError), and parsedmarc handles whichever the installed version provides.
  • The whole codebase (library and tests) now passes pyright with zero errors and warnings, and CI enforces this (plus ruff format --check) on every push and pull request. Pyright is configured in pyproject.toml ([tool.pyright]) and pinned in the [build] extra. The fixes are annotation-level only (Optional parameters, TypedDict-aware signatures on the syslog/GELF save methods, TYPE_CHECKING-aware optional imports for psycopg and the kafka-python 2.x/3.x bootstrap-error fallback) — runtime behavior is unchanged apart from the SyslogClient fix below. Builds on the class-body alias declarations from #797.

Bug fixes

  • SyslogClient: constructing a TCP/TLS client with retry_attempts < 1 now raises ValueError instead of silently skipping the connection loop and registering a broken (None) log handler.

Don't miss a new parsedmarc release

NewReleases is sending notifications on new releases.