Skip to content

kplane-dev/sdk-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kplane Python SDK

pip install kplane — Python SDK for kplane virtual control planes.

kplane gives you thousands of real Kubernetes control planes (≈3MB and ≈50ms per plane). This SDK exposes two primitives that turn that density into something useful for AI/RL workloads:

Primitive What it does Why you want it
plane.state() Aggregate, in-memory snapshot of every resource in a VCP One round-trip to score an agent rollout or capture a trajectory step
client.create_fleet(...) Declare N VCPs, get back an async-iterable handle Parallel RL environments without writing a controller

Install

pip install kplane

Requires Python 3.10+.

Quickstart

import kplane

client = kplane.Client(
    "https://127.0.0.1:6443",
    token="…",            # bearer token
    verify_tls=False,     # for local dev
)

# 1) snapshot a single plane (created on first access)
snap = client.plane("team-alpha").state(warm=True)
print(snap.cluster, snap.live_resources, snap.total_items())

# 2) fleet of N planes for an RL rollout
with client.ephemeral_fleet("rl-rollout", replicas=64) as fleet:
    fleet.wait_until_ready(timeout=120)
    for plane in fleet.planes():
        score = score_state(plane.state())

ephemeral_fleet deletes the Fleet object on context exit. The member VCPs themselves are kept in V0 (intentional — see Deliberate omissions below).

Concepts

Client

Construct once per apiserver. Holds an HTTPX connection pool.

client = kplane.Client(
    "https://127.0.0.1:6443",
    token="…",
    verify_tls=True,
)

Plane

A handle to one virtual control plane. Lightweight — no I/O on construction.

plane = client.plane("team-alpha")
plane.state()                       # full snapshot
plane.state(resource="pods")        # filter
plane.state(resource=["pods", "configmaps"], include_empty=True)
plane.state(warm=True)              # force-create informers on the server
plane.is_ready()                    # cheap /readyz probe

state() returns a Snapshot:

snap.cluster              # str
snap.snapshot_time        # datetime
snap.live_resources       # int — count of resources with informers
snap.resources            # list[SnapshotResource]
snap.by_resource("pods")  # SnapshotResource | None
snap.total_items()        # int — sum of all itemCount

Each SnapshotResource has group, resource, synced, item_count, and items (a list of dict because the items can be any K8s resource shape). metadata.managedFields is stripped server-side to keep payloads tractable.

Fleet

Declarative N-VCP provisioning. The apiserver runs an in-process controller that primes each member through the same bootstrap path organic traffic uses.

fleet = client.create_fleet(
    name="rl-rollout",
    replicas=64,
    name_prefix="rl-",           # optional
    # names=["a", "b", ...],     # OR an explicit list of cluster IDs
)
fleet.wait_until_ready(timeout=120)
fleet.status.ready_replicas      # int
fleet.members                    # list[FleetMember]
fleet.planes()                   # list[Plane], one per member

fleet.refresh()                  # re-fetch from apiserver
fleet.delete()                   # delete the Fleet object (V0: not the VCPs)

For one-shot RL rollouts, use the context-managed helper:

with client.ephemeral_fleet("rl-rollout", replicas=10) as fleet:
    fleet.wait_until_ready()
    ...
# Fleet deleted automatically on exit, even on exception.

OpenAPI

The SDK is generated against a single source-of-truth spec, also embedded in this package:

from kplane.openapi import spec_yaml, load_spec
print(spec_yaml())            # raw YAML
spec = load_spec()            # requires `pip install kplane[yaml]`
print(spec["info"]["version"])

The same document is served live by the apiserver at:

  • GET /openapi/kplane.yaml
  • GET /openapi/kplane.json

These endpoints are server-scoped (not per-VCP) and intentionally unauthenticated so SDK generators and CI can fetch them anonymously.

Deliberate omissions (V0)

These are not shipped yet. Each is a known follow-up rather than a missed feature.

  • No member-VCP garbage collection on Fleet delete. Deleting a Fleet removes the object; the VCPs that were primed by it stay live. This avoids surprise data loss while we get the cleanup semantics right (TTLs, finalizers, scenario isolation).
  • No scenario seeding. A Fleet today provisions empty planes. We expect users to push manifests with the standard kubectl / client-go path in V0 and will move common seeding patterns (Helm chart, kustomize, manifest bundle) into the spec once we see how people use it.
  • No state delta / streaming snapshots. state() returns a full snapshot. The apiserver has the bits to stream deltas (the sdec codec is already there) but the wire format is not finalised.
  • No async client. Sync only. The httpx.AsyncClient based variant is trivial to add but waiting on user demand before locking the surface.
  • No kubectl-style raw resource access. Use the official kubernetes Python client against client.cluster_base_url(cid) for now; we'll either re-export it or wrap the common operations once the surface area is well understood.

Development

pip install -e ".[dev,yaml]"
ruff check src tests
mypy src
pytest -v

Smoke tests against a real apiserver:

export KPLANE_HOST=https://127.0.0.1:6443
export KPLANE_TOKEN=$(cat /tmp/kplane-token)
pytest tests/test_smoke.py -v

License

Apache-2.0. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages