kr8s gives you a kubectl-shaped Python client without generated code
A batteries-included Python client library for Kubernetes that feels familiar for folks who already know how to use kubectl
At a glance
- What is it?
- kr8s is a BSD-3-Clause Python client library for Kubernetes whose API is modelled on kubectl, with hand written code instead of swagger output, client caching, and both a standard and an async surface for asyncio and trio. It covers Python 3.9 to 3.14 and Kubernetes 1.31 to 1.37, and it publishes wheels on PyPI.
- Who is it for?
- kr8s fits a Python team that wants to script cluster operations with the vocabulary of kubectl and ships a wheel on PyPI without generating a client from the OpenAPI spec. It is the wrong choice if you need the entire Kubernetes API surface, including the less used resource types, or if a sync-only codebase is enough.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An API modelled on kubectl, not on the OpenAPI spec
Most Python Kubernetes libraries are generated from the cluster's OpenAPI description, which produces a client that covers everything and reads like a schema dump. kr8s takes the opposite route. The README describes it as a simple, extensible Python client library for Kubernetes that feels familiar for folks who already know how to use kubectl, and one of its listed highlights is human readable code only, with no swagger generated code.
The consequence is a smaller surface with a different shape. You do not call a generic API method with a resource type string, a namespace and a body; you import a class and use methods that mean something, and you can also use a short generic accessor when a list is all you need. The project also advertises batteries included utilities and methods inspired by kubectl, so the goal is that a script written after a week with kubectl still reads naturally.
This is a deliberate trade and it cuts both ways. Hand written code is easier to read and easier to extend, and it can carry the ergonomics of kubectl, but it cannot cover every resource and every verb in the API without growing. The repository layout shows a kr8s/ package, docs/, examples/ and a pyproject.toml, with no separate generated client directory, which matches that description.
The audience is Python developers who already administer clusters and want to automate parts of that work in a script or a service, not someone learning Kubernetes for the first time.
Client caching removes the need to pass API objects around
The second highlight is client caching, documented as a way to reduce passing API objects around. In practice it means the library holds a reference to an object it has already fetched, and a second operation on the same resource reuses that instead of issuing a fresh request and rebuilding the object from scratch. For a script that reads a deployment, then scales it, then reads it again, the difference is a few fewer round trips to the API server.
The object model underneath is what makes that worth having. Resources are classes: Pod, Deployment, Node. Each carries the usual identity, a namespace, and the operations that apply to it. A pod can be labelled, executed into, or port forwarded, a deployment can be scaled, a node can be cordoned. The generic accessor, used for listing, takes a kind string and accepts a label selector and a namespace argument that can be a specific namespace or a constant for all namespaces.
The repository also describes sensible defaults to reduce boilerplate, with a link to the authentication documentation, and separately mentions that the state of things is reachable through the client rather than through explicit calls. The authentication document is where the kubeconfig handling lives, and the README does not duplicate it, so credential precedence is a documentation lookup rather than something visible in the examples.
One API surface, two execution models
kr8s offers both a standard API and an async API, and the async side works with asyncio and with trio. That is a real differentiator, because the common pattern in Python infrastructure tooling is to write the async version and force synchronous callers to run an event loop, or to write the sync version and block a worker thread.
The dependency list gives a hint about how the two coexist. The project depends on anyio, httpx and httpx-ws, and anyio is a library that provides the same asynchronous interface on top of asyncio and trio. The http stack is httpx rather than requests, which is an async capable client, and the websocket client library is present because exec and port forward streams are bidirectional. The test configuration sets asyncio_mode to auto, and the pytest settings include reruns and a timeout of 300 seconds, which suggests the test suite spins up real clusters, consistent with the pytest-kind dependency in the development group.
The practical caveat is that the async and sync surfaces are separate entry points rather than one object that changes behaviour, so a codebase that mixes the two has to be written with that in mind. The README points to the asyncio documentation and to the examples documentation, which includes asyncio examples, rather than spelling out the mapping between the two forms.
Install and first calls
Installation is a single pip command, and the project publishes a wheel on PyPI:
pip install kr8sThe first useful call lists what the cluster is made of. The example prints every node name, using the module level accessor:
import kr8s
for node in kr8s.get("nodes"):
print(node.name)Working with a specific object is done through a class. To scale an existing deployment, the example fetches the Deployment and calls scale on it:
from kr8s.objects import Deployment
deploy = Deployment.get("metrics-server", namespace="kube-system")
deploy.scale(1)To create something, you can either hand over a full manifest as a dictionary, which is the closest thing to kubectl apply, or generate a simple object from keyword arguments:
from kr8s.objects import Pod
pod = Pod.gen(name="example-1", image="nginx:latest")
pod.create()The dictionary form takes the same apiVersion, kind, metadata and spec keys you would put in a YAML manifest, so existing manifests translate directly. For the running pod, exec and port forward are available too, and the port forward example shows the returned object started in a background thread and stopped with a stop call when you are done, which is the pattern to copy if you need a tunnel in a long running script.
Version support and the dependency list you inherit
The badges and the project metadata agree on the supported ranges. Python support runs from 3.9 through 3.14, and the project metadata sets requires-python to >=3.9. Kubernetes support covers versions 1.31 through 1.37, and the documentation link for that badge points at the installation page section on supported Kubernetes versions.
The dependency list is longer than a minimal client needs, and it is worth reading before you commit. Alongside httpx and anyio it pulls in cryptography, pyyaml, python-jsonpath, python-box, cachetools, packaging and typing_extensions, with exceptiongroup and typing_extensions conditioned on Python versions below 3.12. The cryptography dependency comes from the authentication path rather than from the resource layer, and python-box is what gives returned objects attribute access. python-jsonpath suggests that field selection is available on returned data, and cachetools backs the client cache.
Packaging is handled by hatchling with hatch-vcs, and the version is derived from the version control tag through the vcs source, with a version file written into kr8s/_version.py. That means the version of an installed wheel follows the tag it was built from, which is the mechanism behind the release numbering you see on PyPI.
Release cadence and the gap between tags and main
The repository is not archived and the last push was on 2026-10-19, so development is current. The published releases are v0.20.15 on 2026-01-16, v0.20.14 on 2025-12-01 and v0.20.13 on 2025-10-28. Read those two facts together and you get a picture worth planning for: work continues on main, while the tagged releases on PyPI lag behind by a noticeable margin.
The version scheme is not plain semantic versioning. The README carries a badge for EffVer versioning. That is a sensible fit for a client library, since the version of the library has to line up with the version of the API it talks to, and the supported Kubernetes range is documented separately.
The project is BSD-3-Clause, and the tree contains both a LICENSE file and a LICENSE_HEADER, plus an AGENTS.md, a pre-commit configuration and a codecov configuration. Practically, upgrading means pinning a kr8s version that covers your cluster version and accepting that the newest code on main is not what a plain pip install gives you.
Where a different approach makes more sense
The obvious alternative is the standard Python client generated from the Kubernetes OpenAPI document, and the difference in approach is the whole point of kr8s. A generated client exposes the entire API surface with typed models, which matters if you need a rarely used resource or a verb that the curated set does not include, and it also means the method names come from the schema rather than from a design idea. kr8s accepts that coverage limit in exchange for kubectl-shaped ergonomics and hand written code you can read in one sitting.
The other alternative is to skip the library and shell out to kubectl. That gives you the exact same CLI semantics the library is imitating, and it costs you process spawning, text parsing and a subprocess for every call. For a script that runs once and reads three fields, kubectl is often the faster path. For a service that reacts to events and holds long lived objects, an in-process client with client caching is the better fit, and the port forward and exec support exists for exactly those cases where a pure HTTP client would stop short.
Between the two, pick on breadth versus ergonomics. If your task involves standard workloads such as listing nodes, scaling a deployment, creating a pod or cordoning a node, kr8s covers it in a few lines. If it involves the long tail of the API, a generated client or kubectl remains the safer choice, and the README does not claim otherwise.
Editorial conclusion
kr8s fits a Python team that wants to script cluster operations with the vocabulary of kubectl and ships a wheel on PyPI without generating a client from the OpenAPI spec. It is the wrong choice if you need the entire Kubernetes API surface, including the less used resource types, or if a sync-only codebase is enough. Verify first that the Kubernetes version your cluster runs is inside the supported range of 1.31 to 1.37, and that the resource you plan to automate appears in the examples documentation, since the library deliberately covers a curated set of operations rather than the whole API.
Frequently asked questions
What is kr8s and how is it different from the official Kubernetes Python client?
kr8s is a hand written Python client library whose API is modelled on kubectl, with a README that lists no swagger generated code among its highlights. By contrast, kr8s favours a smaller set of readable, kubectl-shaped operations.
How do I install kr8s and list the nodes in my cluster?
Install it with pip install kr8s, then use the module level accessor to iterate the nodes and print each name. The README also links to the authentication documentation for sensible defaults around credentials.
Does kr8s support async Python?
Yes. The project ships a standard API and an async API that works with asyncio and with trio, and the dependency list includes anyio, httpx and httpx-ws. The examples documentation includes asyncio examples.
Which Python and Kubernetes versions does kr8s support?
The project metadata sets requires-python to >=3.9 and the README badge covers Python 3.9 through 3.14. Supported Kubernetes versions run from 1.31 to 1.37.
How is kr8s released and licensed?
It is BSD-3-Clause licensed, built with hatchling and hatch-vcs so the version comes from the version control tag, and it publishes wheels on PyPI. The recent tags are v0.20.15 on 2026-01-16, v0.20.14 on 2025-12-01 and v0.20.13 on 2025-10-28, while the last push was on 2026-10-19.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kr8s-org-kr8s)Was this useful?