NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3387 most downloaded on PyPI
Kubernetes Operator Pythonic Framework (Kopf)
Last release 4 months ago
03 Jun 2026
Ships unpredictably
gaps range from 8 days to 7 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
5 versions withdrawn
withdrawn after publishing
8 years old
127 releases · first in 2019
kubernetes is removed from e2e dependencies. #655
Internal:
kubernetes is removed from e2e dependencies. #655pykube-ng is removed from implicit dependencies. #655pykube-ng & kubernetes are re-exposed via the kopf[full-auth] extra. #655Evade collisions of annotations of ReplicaSets and Deployments. #652
Bugfix:
One column per quarter.
Filtering callbacks (when=, values, labels, annotations) were called for apriori mismatching resources/selectors. #650
Bugfixes:
when=, values, labels, annotations) were called for apriori mismatching resources/selectors. #650Internal:
Assume a singular name is a lowercased kind for builtins (API returns empty names). #629
Bugfixes:
kind: Event from EVERYTHING to avoid "resource explosion". #636Documentation:
kopf.zalando.org/v1 to kopf.dev/v1 (but not annotations and finalizers). #643 #644Other internal changes:
pytest-mock with asynctest. #645BREAKING CHANGES! The major version increase (0.x → 1.x) means that there are changes in the public interface with no backwards compatibility. Pay att…
BREAKING CHANGES! The major version increase (0.x → 1.x) means that there are changes in the public interface with no backwards compatibility. Pay attention when upgrading — most of them have quick replacements.
Most of these legacies are extremely old and it is highly unlikely that they were used in any existing operators. The DeprecationWarnings were issued for all these features (except namespaces). See #511.
| Removed feature | Replacement feature |
|---|---|
cooldown= option of decorators |
backoff= option |
event kwarg in @kopf.on.event |
reason kwarg |
cause kwarg in handlers |
use all kwargs directly |
kopf.login() sync function |
@kopf.on.login handlers and async activities |
kopf.config module |
settings kwarg of @kopf.on.startup() handlers |
kopf.config.get_pykube_cfg() for patching |
@kopf.on.login() handlers |
kopf.HandlerFatalError |
kopf.PermanentError |
kopf.HandlerRetryError |
kopf.TemporaryError |
kopf.create_tasks() (sync) |
kopf.spawn_tasks() (async) |
kopf.events.event/info/warn/exception() |
the same directly in the kopf module |
None for labels=/annotations= filters |
kopf.PRESENT (None now raises exceptions) |
Positional field in @on.field('group', 'v1', 'plural', 'field') |
kwarg field='field' instead |
| Unversioned keys in storages | generate v1/v2 keys explicitly |
| Storages with unprefixed annotations | prefix is now mandatory; defaults to kopf.zalando.org/… |
@kopf.on.this(…) for sub-handlers |
@kopf.subhandler(…) (for readability) |
Dropped without replacements:
OperatorRegistry — use it only as an object for the registry= kwarg. #625 #611Resource[Watching|Spawning|Changing]Registry, ActivityRegistry. #625 #611SimpleRegistry, GlobalRegistry, etc. #625Deprecated:
operator(namespace='…') → operator(namespaces=['…']). #600operator(namespace=None) → operator(clusterwide=True). #600New features:
-n default -n myapp. #500--namespace myapp-*,!*-pr-*. #500@kopf.on.event('kopf.dev', 'kex'). #500@kopf.on.event(kind='Pod'). #500@kopf.on.event('pods'). #500@kopf.on.event(category='all'). #500@kopf.on.event(kopf.EVERYTHING). #500@kopf.on.event(…, field='spec.field', value=kopf.PRESENT). #573@kopf.on.event(…, field='spec.field', value='value'); callbacks are supported. #573@kopf.on.update(…, field='spec.field', old=1, new=2); callbacks are supported. #573Improvements:
x-kubernetes-preserve-unknown-fields in the docs. #612Bugfixes:
Contributor experience:
Renamed @kopf.on.this to @kopf.subhandler for readability. #618
Enhancements:
@kopf.on.this to @kopf.subhandler for readability. #618Bugfixes:
Internals:
kopf.execute() to be asynchronous. #618Fixed superseding of one cause by another (deletion-during-creation/-update/-resume, update-during-resume, etc). #607 #606
Bugfixes:
Fixed superseding of one cause by another (deletion-during-creation/-update/-resume, update-during-resume, etc). #607 #606
Bugfixes:
No more false "patching failed with inconsistencies" warning for CRDs with status as a subresource. #588
Bugfixes:
Internal:
General topic: stability, resilience, recoverability, better logging and error handling.
General topic: stability, resilience, recoverability, better logging and error handling.
New features:
--log-format=json. #544--log-format=plain. #544Bugfixes:
None→None change. #523Resilience improvements:
Experience improvements:
Internal changes:
isort. #525 #531Log when the patched object disappears (e.g. is deleted). Omit inconsistency warnings for this. #559
Experience improvements:
K8s API errors contain the explanations from K8s API itself, not from an HTTP client library. #558
Experience improvements:
Persisted states of executed and then filtered-out handlers were not purged. #557
Bugfixes:
Timers were ticking forever after the resource was deleted (if there were no finalizers). #548
Bugfixes:
General topic: stability, resilience, recoverability, better logging and error handling.
General topic: stability, resilience, recoverability, better logging and error handling.
New features:
--log-format=json. #544--log-format=plain. #544Bugfixes:
None→None change. #523Resilience improvements:
Experience improvements:
Internal changes:
isort. #525 #531Support Python 3.9 with Kopf's 0.27 codebase and features. #562
Bugfixes:
> _Originally released on 2020-05-11 16:37:41+00:00 (link)._
Originally released on 2020-05-11 16:37:41+00:00 (link).
WARNING: The changes are backward-compatible (in theory). But the changes are also massive, so things can break unexpectedly (in practice). Test this upgrade carefully.
New features:
@kopf.daemon for background resource-accompanying tasks/threads. #330 #342 #360@kopf.timer for regular and/or delayed activities & checks. #330 #342 #360kopf.PRESENT for labels/annotations filters (instead of misleading None). #327kopf.ABSENT for labels/annotations filters. #327kopf.all_(), kopf.any_(), kopf.not_(), kopf.none_() helpers for callbacks aggregation. #345Improvements:
KopfExample & KopfPeering from v1beta1 to v1 CRD API; keep v1beta1 nearby. #364Fixes:
Internal changes:
pytest & pytest-asyncio are pinned temporarily until fixed on their side. #352> _Originally released on 2020-05-11 16:37:41+00:00 (link)._
Originally released on 2020-05-11 16:37:41+00:00 (link).
Documentation:
KopfExample & KopfPeering from v1beta1 to v1 CRD API; keep v1beta1 nearby. #364Fixes:
Internal changes:
> _Originally released on 2020-04-28 12:29:32+00:00 (link)._
Originally released on 2020-04-28 12:29:32+00:00 (link).
Fixes:
Internal changes:
pytest & pytest-asyncio are pinned temporarily until fixed on their side. #352> _Originally released on 2020-04-16 17:02:14+00:00 (link)._
Originally released on 2020-04-16 17:02:14+00:00 (link).
Fixes:
> _Originally released on 2020-04-08 14:52:29+00:00 (link)._
Originally released on 2020-04-08 14:52:29+00:00 (link).
Improvements:
kopf.all_(), kopf.any_(), kopf.not_(), kopf.none_() helpers for callbacks aggregation. #345> _Originally released on 2020-04-07 12:07:16+00:00 (link)._
Originally released on 2020-04-07 12:07:16+00:00 (link).
Improvements:
Fixes:
> _Originally released on 2020-04-01 10:17:05+00:00 (link)._
Originally released on 2020-04-01 10:17:05+00:00 (link).
WARNING: The changes are backward-compatible (in theory). But the changes are also massive, so things can break unexpectedly (in practice). Test this upgrade carefully.
New features:
@kopf.daemon for background resource-accompanying tasks/threads. #330@kopf.timer for regular and/or delayed activities & checks. #330kopf.PRESENT for labels/annotations filters (instead of misleading None). #327kopf.ABSENT for labels/annotations filters. #327Improvements:
Fixes:
Internal changes:
Deprecate prefixes and proxying methods of registries, make registries simpler. #315
Originally released on 2020-02-20 16:05:16+00:00 (link).
Improvements:
Authorization: and other HTTP headers in logs. #306CI/CD automation:
Internal changes:
Deprecate prefixes and proxying methods of registries, make registries simpler. #315
Originally released on 2020-02-20 16:05:16+00:00 (link).
Improvements:
Authorization: and other HTTP headers in logs. #306CI/CD automation:
Internal changes:
> _Originally released on 2020-01-29 14:04:33+00:00 (link)._
Originally released on 2020-01-29 14:04:33+00:00 (link).
New features:
when= option. #258 #288Bugfixes:
Internal improvements:
> _Originally released on 2020-01-17 16:32:12+00:00 (link)._
Originally released on 2020-01-17 16:32:12+00:00 (link).
New features:
when= option. #258 #288Bugfixes:
Internal improvements:
> _Originally released on 2019-12-19 13:44:56+00:00 (link)._
Originally released on 2019-12-19 13:44:56+00:00 (link).
Improvements:
cooldown is renamed to backoff to match the usual terminology. #266Bugfixes:
Internal changes:
> _Originally released on 2019-12-19 13:44:56+00:00 (link)._
Originally released on 2019-12-19 13:44:56+00:00 (link).
Improvements:
cooldown is renamed to backoff to match the usual terminology. #266Bugfixes:
Internal changes:
> _Originally released on 2019-11-21 12:53:24+00:00 (link)._
Originally released on 2019-11-21 12:53:24+00:00 (link).
Bugfixes:
> _Originally released on 2019-11-20 18:06:35+00:00 (link)._
Originally released on 2019-11-20 18:06:35+00:00 (link).
Bugfixes:
> _Originally released on 2019-11-20 10:15:07+00:00 (link)._
Originally released on 2019-11-20 10:15:07+00:00 (link).
TL;DR: Massive refactoring, renames, code moves. Generally, should be backward-compatible.
RISKY CHANGES (can be BREAKING, should be not):
pykube-ng and kubernetes clients are now piggybacked by default to extract the endpoints and credentials, but are not used for the API communication. This can break API connectivity in some cases. #226 #227@kopf.on.resume() handlers were fixed, and now execute when previously they were not executed by mistake, but this could be taken as an expected behaviour. This can lead to massive patches of all resumable objects on every operator startup (if there are 2+ handlers), which can be a problem in huge clusters. #230 #236New features:
@kopf.on.startup() handlers for operator initialisation. #225@kopf.on.cleanup() handlers for operator shutdown. #225@kopf.on.login() custom authentication handlers. #226@kopf.on.probe() handlers for liveness metrics. #226kopf run --liveness. #228memo kwargs to keep runtime-only operator-lifetime-limited arbitrary values. #234retries= limiter for handlers in addition to timeout=. #222errors=TEMPORARY, errors=PERMANENT, errors=IGNORED modes for handlers. #222kopf.adopt() and hierarchy methods, current object is used by default. #203Bugfixes:
@kopf.on.resume() handlers fixed:
spec, status, metadata fields are not added to the body when originally absent. #198Internal changes:
cause.event is renamed to cause.reason to avoid terminology conflicts. #201kex is added as an alias for KopfExample CRD for demos/docs. #235> _Originally released on 2019-11-20 01:11:43+00:00 (link)._
Originally released on 2019-11-20 01:11:43+00:00 (link).
Bugfixes:
Authorization: Bearer is not injected by default, breaking username+password auth. #243> _Originally released on 2019-11-15 11:42:02+00:00 (link)._
Originally released on 2019-11-15 11:42:02+00:00 (link).
Internal changes:
kex as an alias for KopfExample CRD for demos/docs. #235> _Originally released on 2019-11-14 13:47:58+00:00 (link)._
Originally released on 2019-11-14 13:47:58+00:00 (link).
New features:
memo kwargs to keep the runtime-only operator-lifetime-limited arbitrary values. #234> _Originally released on 2019-11-14 11:10:09+00:00 (link)._
Originally released on 2019-11-14 11:10:09+00:00 (link).
Improvements:
@kopf.on.resume() handlers are not invoked if the object is being deleted. #233@kopf.on.resume() can be explicitly marked as a deletion-safe handler. #233> _Originally released on 2019-11-13 14:07:04+00:00 (link)._
Originally released on 2019-11-13 14:07:04+00:00 (link).
TL;DR: Massive refactoring, renames, code moves. Generally, should be backward-compatible.
RISKY CHANGES (can be BREAKING, should be not):
pykube-ng and kubernetes clients are now piggybacked by default to extract the endpoints and credentials, but are not used for the API communication. This can break API connectivity in some cases. #226 #227@kopf.on.resume() handlers were fixed, and can now execute when previously they were not executed by mistake, but this could be taken as an expected behaviour. This can lead to massive patches of all objects on every operator startup. #230cause.event is renamed to cause.reason to avoid terminology conflicts. #201New features:
@kopf.on.startup() handlers for operator initialisation. #225@kopf.on.cleanup() handlers for operator shutdown. #225@kopf.on.login() custom authentication handlers. #226@kopf.on.probe() handlers for liveness metrics. #226kopf run --liveness. #228kopf.adopt() and hierarchy methods, current object is used by default. #203retries= limiter for handlers in addition to timeout=. #222errors=TEMPORARY, errors=PERMANENT, errors=IGNORED modes for handlers. #222Bugfixes:
@kopf.on.resume() handlers are not repeated every few minutes for no reason. #229 #230@kopf.on.resume() are executed if they go after the on-create/on-update handlers. #230@kopf.on.resume() can be retried in case of temporary or arbitrary errors. #230@kopf.on.resume() can have sub-handlers. #230@kopf.on.resume() handlers. #230spec, status, metadata fields are not added to the body when absent. #198Internal changes:
> _Originally released on 2019-10-23 17:19:02+00:00 (link)._
Originally released on 2019-10-23 17:19:02+00:00 (link).
Bugfixes:
Internal changes:
> _Originally released on 2019-09-26 10:56:43+00:00 (link)._
Originally released on 2019-09-26 10:56:43+00:00 (link).
Bugfixes:
Internal changes:
> _Originally released on 2019-09-13 11:01:50+00:00 (link)._
Originally released on 2019-09-13 11:01:50+00:00 (link).
New features:
Improvements:
kopf --version added. #175kopf.PermanentError/kopf.TemporaryError. #159Bugfixes:
Internal changes:
> _Originally released on 2019-08-14 17:35:01+00:00 (link)._
Originally released on 2019-08-14 17:35:01+00:00 (link).
Reverted:
> _Originally released on 2019-08-12 07:38:22+00:00 (link)._
Originally released on 2019-08-12 07:38:22+00:00 (link).
Improvements:
> _Originally released on 2019-08-08 14:54:13+00:00 (link)._
Originally released on 2019-08-08 14:54:13+00:00 (link).
Improvements:
kopf --version added. #175Bugfixes:
> _Originally released on 2019-08-08 13:23:01+00:00 (link)._
Originally released on 2019-08-08 13:23:01+00:00 (link).
Improvements:
Bugfixes:
> _Originally released on 2019-08-07 17:45:34+00:00 (link)._
Originally released on 2019-08-07 17:45:34+00:00 (link).
New features:
Improvements:
kopf.PermanentError/kopf.TemporaryError. #159Internal changes:
> _Originally released on 2019-07-24 09:25:51+00:00 (link)._
Originally released on 2019-07-24 09:25:51+00:00 (link).
New feature:
> _Originally released on 2019-07-16 10:09:39+00:00 (link)._
Originally released on 2019-07-16 10:09:39+00:00 (link).
New features:
logger kwarg (INFO+ level) are sent as Kubernetes events implicitly. #128 #148Improvements:
Internal changes:
> _Originally released on 2019-07-12 11:30:47+00:00 (link)._
Originally released on 2019-07-12 11:30:47+00:00 (link).
Bugfixes:
> _Originally released on 2019-07-09 13:11:00+00:00 (link)._
Originally released on 2019-07-09 13:11:00+00:00 (link).
Improvements:
Internal changes:
> _Originally released on 2019-07-08 12:42:48+00:00 (link)._
Originally released on 2019-07-08 12:42:48+00:00 (link).
Improvements:
.status is ignored in the last-handled state checks (except for fields used in field-handlers). #131.metadata is ignored in the last-handled state checks (except for labels & annotations). #131Bugfixes:
kubernetes<10.0.0 to keep Kopf runnable at all. #134Internal changes:
> _Originally released on 2019-07-04 12:45:51+00:00 (link)._
Originally released on 2019-07-04 12:45:51+00:00 (link).
Hotfix:
kubernetes<10.0.0 to keep Kopf runnable at all.See: #134 and kubernetes-client/python#866
> _Originally released on 2019-07-03 08:23:43+00:00 (link)._
Originally released on 2019-07-03 08:23:43+00:00 (link).
Improvements:
Internal changes:
kopf.engines extracted from kopf.reactor (peering & posting & logging).kopf.utilities extracted from kopf.reactor (reacting to k8s changes).kopf.clients is the new kopf.k8s (renamed).kopf.clients.auth extracted from kopf.config (only auth-related routines).kopf.config got the configuration constants from all over the code.Nothing published for this version
> _Originally released on 2019-06-14 09:18:57+00:00 (link)._
Originally released on 2019-06-14 09:18:57+00:00 (link).
New features:
@kopf.on.resume for threads/tasks. #105Internal changes:
event['type']=="ADDED", but event['type']==None). The watching continues from the resource-version of the list, as it must be by design. #105*The release is done as a rollback point from 0.16 if the resume-handlers introduce breaking changes (they shouldn't).*
Originally released on 2019-06-13 16:14:01+00:00 (link).
New features:
@kopf.on.event (currently only for custom resources). #86Improvements:
Internal changes:
The release is done as a rollback point from 0.16 if the resume-handlers introduce breaking changes (they shouldn't).
> _Originally released on 2019-05-31 14:44:45+00:00 (link)._
Originally released on 2019-05-31 14:44:45+00:00 (link).
Bugfixes:
Other changes:
@kopf.on.field() handler. #69> _Originally released on 2019-05-28 14:42:06+00:00 (link)._
Originally released on 2019-05-28 14:42:06+00:00 (link).
Bugs fixed:
v1 instead of v1beta1 API, making it compatible with Google Kubernetes Engine >=1.12. #81Other changes:
> _Originally released on 2019-05-28 09:06:00+00:00 (link)._
Originally released on 2019-05-28 09:06:00+00:00 (link).
New features:
namespace, name, uid kwargs for the handlers (were mentioned in the docs, absent in the code).Other changes:
> _Originally released on 2019-05-17 12:06:39+00:00 (link)._
Originally released on 2019-05-17 12:06:39+00:00 (link).
Breaking change:
KopfPeering (cluster-scoped) is now ClusterKopfPeering.KopfPeering is made namespaced.Other changes:
metadata.generation does not trigger the update handlers in Minikube anymore.> _Originally released on 2019-04-26 15:15:00+00:00 (link)._
Originally released on 2019-04-26 15:15:00+00:00 (link).
Your coding agent can read these notes before it upgrades. Set up the MCP server →