or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-apis.mdconfiguration.mddynamic-client.mdindex.mdleader-election.mdstreaming.mdutils.mdwatch.md

dynamic-client.mddocs/

0

# Dynamic Client

1

2

Runtime API discovery and interaction with any Kubernetes resource, including custom resources defined by Custom Resource Definitions (CRDs). The dynamic client enables working with resources not known at compile time and provides a flexible interface for any Kubernetes API.

3

4

## Capabilities

5

6

### Dynamic Client

7

8

The main entry point for dynamic Kubernetes API interactions with automatic resource discovery.

9

10

```python { .api }

11

class DynamicClient:

12

def __init__(self, client, cache_file=None, discoverer=None):

13

"""

14

Initialize dynamic client with API discovery.

15

16

Parameters:

17

- client: ApiClient, authenticated Kubernetes API client

18

- cache_file: str, path to cache discovered API resources (optional)

19

- discoverer: Discoverer, custom discovery implementation (optional)

20

"""

21

22

async def __aenter__(self):

23

"""Async context manager entry."""

24

25

async def __aexit__(self, exc_type, exc_val, exc_tb):

26

"""Async context manager exit with cleanup."""

27

28

@property

29

def resources(self):

30

"""

31

Access to discovered resources.

32

33

Returns:

34

- ResourceRegistry: Registry of all discovered API resources

35

"""

36

37

@property

38

def version(self):

39

"""

40

Kubernetes API server version information.

41

42

Returns:

43

- dict: Version details including major, minor, git version, etc.

44

"""

45

```

46

47

### Resource Access

48

49

Interface for accessing and manipulating any Kubernetes resource type dynamically.

50

51

```python { .api }

52

class Resource:

53

def __init__(self, api_version, kind, client, **kwargs):

54

"""

55

Represents a Kubernetes API resource type.

56

57

Parameters:

58

- api_version: str, API version (e.g., "v1", "apps/v1")

59

- kind: str, resource kind (e.g., "Pod", "Deployment")

60

- client: DynamicClient, parent dynamic client

61

"""

62

63

def get(self, name=None, namespace=None, label_selector=None, field_selector=None, **kwargs):

64

"""

65

Get resource(s) by name or selectors.

66

67

Parameters:

68

- name: str, specific resource name (for single resource)

69

- namespace: str, namespace to search (for namespaced resources)

70

- label_selector: str, label selector query

71

- field_selector: str, field selector query

72

- **kwargs: Additional query parameters

73

74

Returns:

75

- ResourceInstance or ResourceList: Single resource or list of resources

76

"""

77

78

def create(self, body=None, namespace=None, **kwargs):

79

"""

80

Create a new resource.

81

82

Parameters:

83

- body: dict, resource definition

84

- namespace: str, target namespace (for namespaced resources)

85

- **kwargs: Additional creation parameters

86

87

Returns:

88

- ResourceInstance: Created resource

89

"""

90

91

def patch(self, body=None, name=None, namespace=None, **kwargs):

92

"""

93

Partially update a resource.

94

95

Parameters:

96

- body: dict, patch data

97

- name: str, resource name to patch

98

- namespace: str, resource namespace (for namespaced resources)

99

- **kwargs: Additional patch parameters

100

101

Returns:

102

- ResourceInstance: Updated resource

103

"""

104

105

def replace(self, body=None, name=None, namespace=None, **kwargs):

106

"""

107

Replace entire resource.

108

109

Parameters:

110

- body: dict, complete resource definition

111

- name: str, resource name to replace

112

- namespace: str, resource namespace (for namespaced resources)

113

- **kwargs: Additional replace parameters

114

115

Returns:

116

- ResourceInstance: Replaced resource

117

"""

118

119

def delete(self, name=None, namespace=None, label_selector=None, field_selector=None, **kwargs):

120

"""

121

Delete resource(s).

122

123

Parameters:

124

- name: str, specific resource name

125

- namespace: str, resource namespace (for namespaced resources)

126

- label_selector: str, label selector for bulk deletion

127

- field_selector: str, field selector for bulk deletion

128

- **kwargs: Additional deletion parameters

129

130

Returns:

131

- ResourceInstance or ResourceList: Deleted resource(s) or status

132

"""

133

134

def watch(self, namespace=None, name=None, label_selector=None, field_selector=None,

135

resource_version=None, timeout_seconds=None, **kwargs):

136

"""

137

Watch for resource changes.

138

139

Parameters:

140

- namespace: str, namespace to watch (for namespaced resources)

141

- name: str, specific resource name to watch

142

- label_selector: str, label selector for filtering

143

- field_selector: str, field selector for filtering

144

- resource_version: str, resource version to start watching from

145

- timeout_seconds: int, watch timeout

146

- **kwargs: Additional watch parameters

147

148

Returns:

149

- generator: Stream of watch events

150

"""

151

152

@property

153

def subresources(self):

154

"""

155

Access to resource subresources (scale, status, etc.).

156

157

Returns:

158

- dict: Mapping of subresource names to Subresource objects

159

"""

160

```

161

162

### Resource Objects

163

164

Wrappers for individual Kubernetes resource instances with convenient access patterns.

165

166

```python { .api }

167

class ResourceInstance:

168

def __init__(self, resource, instance):

169

"""

170

Wrapper for individual Kubernetes resource.

171

172

Parameters:

173

- resource: Resource, parent resource type

174

- instance: dict, resource data from API

175

"""

176

177

@property

178

def metadata(self):

179

"""Resource metadata (name, namespace, labels, annotations, etc.)."""

180

181

@property

182

def spec(self):

183

"""Resource specification."""

184

185

@property

186

def status(self):

187

"""Resource status."""

188

189

def to_dict(self):

190

"""Convert to dictionary representation."""

191

192

def patch(self, body=None, **kwargs):

193

"""Patch this specific resource instance."""

194

195

def replace(self, body=None, **kwargs):

196

"""Replace this specific resource instance."""

197

198

def delete(self, **kwargs):

199

"""Delete this specific resource instance."""

200

201

class ResourceList:

202

def __init__(self, resource, items):

203

"""

204

List of Kubernetes resources.

205

206

Parameters:

207

- resource: Resource, parent resource type

208

- items: list, resource instances

209

"""

210

211

@property

212

def items(self):

213

"""List of ResourceInstance objects."""

214

215

@property

216

def metadata(self):

217

"""List metadata (resource version, continue token, etc.)."""

218

219

def to_dict(self):

220

"""Convert entire list to dictionary representation."""

221

```

222

223

### Subresources

224

225

Access to Kubernetes subresources like scale, status, and custom subresources.

226

227

```python { .api }

228

class Subresource:

229

def __init__(self, parent_resource, name):

230

"""

231

Kubernetes resource subresource.

232

233

Parameters:

234

- parent_resource: Resource, parent resource type

235

- name: str, subresource name (e.g., "scale", "status")

236

"""

237

238

def get(self, name, namespace=None, **kwargs):

239

"""Get subresource for specific parent resource."""

240

241

def patch(self, name, body, namespace=None, **kwargs):

242

"""Patch subresource for specific parent resource."""

243

244

def replace(self, name, body, namespace=None, **kwargs):

245

"""Replace subresource for specific parent resource."""

246

```

247

248

### Discovery System

249

250

API discovery implementations for loading Kubernetes API resources at runtime.

251

252

```python { .api }

253

class EagerDiscoverer:

254

def __init__(self, client, cache_file=None):

255

"""

256

Pre-loads all API resource information at initialization.

257

258

Parameters:

259

- client: ApiClient, authenticated Kubernetes client

260

- cache_file: str, path to cache file for discovered resources

261

"""

262

263

def get_resources_for_api_version(self, prefix, group_version):

264

"""Get all resources for specific API version."""

265

266

class LazyDiscoverer:

267

def __init__(self, client, cache_file=None):

268

"""

269

Loads API resources on-demand as they are accessed (default).

270

271

Parameters:

272

- client: ApiClient, authenticated Kubernetes client

273

- cache_file: str, path to cache file for discovered resources

274

"""

275

276

def get_resources_for_api_version(self, prefix, group_version):

277

"""Get resources for API version, loading if not cached."""

278

```

279

280

### Exception Classes

281

282

Dynamic client specific exceptions for error handling.

283

284

```python { .api }

285

class KubernetesValidateMissing(Exception):

286

"""Raised when kubernetes-validate library is not available for client-side validation."""

287

288

def api_exception(e):

289

"""

290

Wrapper function that converts API exceptions to appropriate types.

291

292

Parameters:

293

- e: Exception, original API exception

294

295

Returns:

296

- Exception: Appropriately typed exception

297

"""

298

```

299

300

## Usage Examples

301

302

### Basic Dynamic Client Usage

303

304

```python

305

import asyncio

306

from kubernetes_asyncio import client, config, dynamic

307

308

async def basic_dynamic():

309

await config.load_config()

310

api_client = client.ApiClient()

311

312

async with dynamic.DynamicClient(api_client) as dyn_client:

313

# Access any Kubernetes resource

314

pods = dyn_client.resources.get(api_version="v1", kind="Pod")

315

316

# List all pods across all namespaces

317

pod_list = pods.get()

318

print(f"Found {len(pod_list.items)} pods")

319

320

# List pods in specific namespace

321

default_pods = pods.get(namespace="default")

322

for pod in default_pods.items:

323

print(f"Pod: {pod.metadata.name} in {pod.metadata.namespace}")

324

325

asyncio.run(basic_dynamic())

326

```

327

328

### Working with Custom Resources

329

330

```python

331

async def custom_resources():

332

await config.load_config()

333

api_client = client.ApiClient()

334

335

async with dynamic.DynamicClient(api_client) as dyn_client:

336

# Access custom resource (assuming CRD exists)

337

custom_resource = dyn_client.resources.get(

338

api_version="example.com/v1",

339

kind="MyCustomResource"

340

)

341

342

# Create custom resource

343

custom_obj = {

344

"apiVersion": "example.com/v1",

345

"kind": "MyCustomResource",

346

"metadata": {

347

"name": "my-custom-object",

348

"namespace": "default"

349

},

350

"spec": {

351

"replicas": 3,

352

"template": "nginx"

353

}

354

}

355

356

created = custom_resource.create(body=custom_obj, namespace="default")

357

print(f"Created custom resource: {created.metadata.name}")

358

359

# List custom resources

360

custom_list = custom_resource.get(namespace="default")

361

for item in custom_list.items:

362

print(f"Custom resource: {item.metadata.name}")

363

364

asyncio.run(custom_resources())

365

```

366

367

### Resource Discovery and Exploration

368

369

```python

370

async def explore_resources():

371

await config.load_config()

372

api_client = client.ApiClient()

373

374

async with dynamic.DynamicClient(api_client) as dyn_client:

375

# Explore available API resources

376

print(f"Kubernetes version: {dyn_client.version}")

377

378

# Get all available resources

379

all_resources = dyn_client.resources.search()

380

381

print("Available API resources:")

382

for resource in all_resources:

383

print(f" {resource.api_version}/{resource.kind} - {resource.name}")

384

385

# Find resources by kind

386

deployment_resources = dyn_client.resources.search(kind="Deployment")

387

for res in deployment_resources:

388

print(f"Deployment resource: {res.api_version}/{res.kind}")

389

390

asyncio.run(explore_resources())

391

```

392

393

### Watching Resources

394

395

```python

396

async def watch_resources():

397

await config.load_config()

398

api_client = client.ApiClient()

399

400

async with dynamic.DynamicClient(api_client) as dyn_client:

401

pods = dyn_client.resources.get(api_version="v1", kind="Pod")

402

403

# Watch for pod changes in default namespace

404

print("Watching for pod changes...")

405

406

async for event in pods.watch(namespace="default", timeout_seconds=300):

407

event_type = event['type'] # ADDED, MODIFIED, DELETED

408

pod = event['object']

409

print(f"{event_type}: Pod {pod.metadata.name} - {pod.status.phase}")

410

411

asyncio.run(watch_resources())

412

```

413

414

### Scaling Deployments

415

416

```python

417

async def scale_deployment():

418

await config.load_config()

419

api_client = client.ApiClient()

420

421

async with dynamic.DynamicClient(api_client) as dyn_client:

422

deployments = dyn_client.resources.get(api_version="apps/v1", kind="Deployment")

423

424

# Get current deployment

425

deployment = deployments.get(name="nginx-deployment", namespace="default")

426

print(f"Current replicas: {deployment.spec.replicas}")

427

428

# Scale using the scale subresource

429

scale_resource = deployments.subresources["scale"]

430

current_scale = scale_resource.get(name="nginx-deployment", namespace="default")

431

432

# Update replica count

433

new_scale = {

434

"apiVersion": "autoscaling/v1",

435

"kind": "Scale",

436

"metadata": current_scale.metadata.to_dict(),

437

"spec": {"replicas": 5}

438

}

439

440

updated_scale = scale_resource.replace(

441

name="nginx-deployment",

442

namespace="default",

443

body=new_scale

444

)

445

print(f"Scaled to {updated_scale.spec.replicas} replicas")

446

447

asyncio.run(scale_deployment())

448

```

449

450

### Bulk Operations with Label Selectors

451

452

```python

453

async def bulk_operations():

454

await config.load_config()

455

api_client = client.ApiClient()

456

457

async with dynamic.DynamicClient(api_client) as dyn_client:

458

pods = dyn_client.resources.get(api_version="v1", kind="Pod")

459

460

# List pods with specific labels

461

labeled_pods = pods.get(

462

namespace="default",

463

label_selector="app=nginx,env=production"

464

)

465

466

print(f"Found {len(labeled_pods.items)} nginx production pods")

467

468

# Patch all matching pods

469

for pod in labeled_pods.items:

470

patch_body = {

471

"metadata": {

472

"annotations": {

473

"last-updated": "2024-01-15T10:00:00Z"

474

}

475

}

476

}

477

478

patched = pods.patch(

479

name=pod.metadata.name,

480

namespace=pod.metadata.namespace,

481

body=patch_body

482

)

483

print(f"Patched pod: {patched.metadata.name}")

484

485

asyncio.run(bulk_operations())

486

```