Metadata-Version: 2.5
Name: cloudcoil
Version: 0.7.0
Summary: Cloud native made easy with Python
Project-URL: Homepage, https://github.com/cloudcoil/cloudcoil
Project-URL: Documentation, https://cloudcoil.github.io/cloudcoil
Project-URL: Repository, https://github.com/cloudcoil/cloudcoil
Project-URL: Issues, https://github.com/cloudcoil/cloudcoil/issues
Project-URL: Changelog, https://github.com/cloudcoil/cloudcoil/releases
Author-email: Sambhav Kothari <sambhavs.email@gmail.com>
Maintainer-email: Sambhav Kothari <sambhavs.email@gmail.com>
License: Apache-2.0
License-File: LICENSE
Keywords: async,cloud-native,kubernetes,pydantic,python
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.14
Requires-Dist: httpx
Requires-Dist: pydantic<3,>=2.12
Requires-Dist: pyyaml>=6.0.2
Provides-Extra: all-models
Requires-Dist: cloudcoil-models-cert-manager; extra == 'all-models'
Requires-Dist: cloudcoil-models-fluxcd; extra == 'all-models'
Requires-Dist: cloudcoil-models-istio; extra == 'all-models'
Requires-Dist: cloudcoil-models-keda; extra == 'all-models'
Requires-Dist: cloudcoil-models-knative-eventing; extra == 'all-models'
Requires-Dist: cloudcoil-models-knative-serving; extra == 'all-models'
Requires-Dist: cloudcoil-models-kpack; extra == 'all-models'
Requires-Dist: cloudcoil-models-kubernetes; extra == 'all-models'
Requires-Dist: cloudcoil-models-kyverno; extra == 'all-models'
Requires-Dist: cloudcoil-models-prometheus-operator; extra == 'all-models'
Requires-Dist: cloudcoil-models-sealed-secrets; extra == 'all-models'
Requires-Dist: cloudcoil-models-velero; extra == 'all-models'
Provides-Extra: cert-manager
Requires-Dist: cloudcoil-models-cert-manager; extra == 'cert-manager'
Provides-Extra: codegen
Requires-Dist: datamodel-code-generator[http]<0.73,>=0.72; extra == 'codegen'
Requires-Dist: ruff; extra == 'codegen'
Provides-Extra: fluxcd
Requires-Dist: cloudcoil-models-fluxcd; extra == 'fluxcd'
Provides-Extra: istio
Requires-Dist: cloudcoil-models-istio; extra == 'istio'
Provides-Extra: keda
Requires-Dist: cloudcoil-models-keda; extra == 'keda'
Provides-Extra: knative-eventing
Requires-Dist: cloudcoil-models-knative-eventing; extra == 'knative-eventing'
Provides-Extra: knative-serving
Requires-Dist: cloudcoil-models-knative-serving; extra == 'knative-serving'
Provides-Extra: kpack
Requires-Dist: cloudcoil-models-kpack; extra == 'kpack'
Provides-Extra: kubernetes
Requires-Dist: cloudcoil-models-kubernetes; extra == 'kubernetes'
Provides-Extra: kubernetes-1-29
Requires-Dist: cloudcoil-models-kubernetes~=1.29.0; extra == 'kubernetes-1-29'
Provides-Extra: kubernetes-1-30
Requires-Dist: cloudcoil-models-kubernetes~=1.30.0; extra == 'kubernetes-1-30'
Provides-Extra: kubernetes-1-31
Requires-Dist: cloudcoil-models-kubernetes~=1.31.0; extra == 'kubernetes-1-31'
Provides-Extra: kubernetes-1-32
Requires-Dist: cloudcoil-models-kubernetes~=1.32.0; extra == 'kubernetes-1-32'
Provides-Extra: kyverno
Requires-Dist: cloudcoil-models-kyverno; extra == 'kyverno'
Provides-Extra: operator
Requires-Dist: uvicorn<1,>=0.38; extra == 'operator'
Provides-Extra: prometheus-operator
Requires-Dist: cloudcoil-models-prometheus-operator; extra == 'prometheus-operator'
Provides-Extra: sealed-secrets
Requires-Dist: cloudcoil-models-sealed-secrets; extra == 'sealed-secrets'
Provides-Extra: test
Requires-Dist: filelock; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: pytest-asyncio; extra == 'test'
Provides-Extra: truststore
Requires-Dist: truststore>=0.8.0; extra == 'truststore'
Provides-Extra: velero
Requires-Dist: cloudcoil-models-velero; extra == 'velero'
Description-Content-Type: text/markdown

# cloudcoil

Typed Kubernetes clients, controllers and admission policies for Python 3.14.

[![PyPI](https://img.shields.io/pypi/v/cloudcoil.svg)](https://pypi.org/project/cloudcoil/)
[![CI](https://github.com/cloudcoil/cloudcoil/actions/workflows/ci.yml/badge.svg)](https://github.com/cloudcoil/cloudcoil/actions/workflows/ci.yml)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)

Use Pydantic resource classes for typed API calls. Build controllers that return
changed resources, define CRDs from Python models, and add admission policies to
built-in or custom resources.

## Installation

```sh
uv add 'cloudcoil[kubernetes]'
# Include HTTPS hosting for admission:
uv add 'cloudcoil[operator,kubernetes]'
```

The Kubernetes extra currently installs published 1.32 models. Until supported
model packages are released, follow the [checkout installation instructions](docs/getting-started.md#install)
to generate matching models. See [VERSIONING.md](VERSIONING.md) for Kubernetes support
and migration details.

## Read resources

```python
from cloudcoil.models.kubernetes.core.v1 import Pod

for pod in Pod.list(namespace="default").items:
    print(pod.name)
```

Async applications use `await Pod.async_list(...)`. Cloudcoil uses your kubeconfig
locally and ServiceAccount credentials in a Pod.

## Write a controller

```python
from cloudcoil.controller import Controller, Request
from cloudcoil.models.kubernetes.core.v1 import ConfigMap
from cloudcoil.application import Application

async def reconcile(request: Request[ConfigMap]) -> ConfigMap | None:
    obj = request.resource
    if obj is None or (obj.metadata and obj.metadata.deletion_timestamp):
        return None
    obj.data = {**(obj.data or {}), "managed-by": "cloudcoil"}
    return obj

app = Application(
    "configmap-labeler",
    Controller(ConfigMap, reconcile, label_selector="example.com/manage=true"),
)

if __name__ == "__main__":
    app.main()
```

Save as `app.py`. Run `python app.py manifests` to review generated permissions,
or `python app.py run` to start reconciliation. Cloudcoil handles watch recovery,
retries, guarded main/status patches and shutdown. Unchanged returns cause no write.
See the [quickstart](docs/getting-started.md) to try it against a cluster.

## Documentation

The [documentation site](https://cloudcoil.github.io/cloudcoil/) contains the full guides.
The same pages are available in this checkout:

| Task | Guide |
| --- | --- |
| Install and run your first controller | [Getting started](docs/getting-started.md) |
| API operations and builders | [Resources](docs/resources.md) |
| Workload logs | [Logs](docs/logs.md) |
| CRD/OpenAPI model generation and typing | [Models](docs/models.md) |
| Define CRDs from Python | [Custom resources](docs/custom-resources.md) |
| Reconcile, manage children and write status | [Controllers](docs/controllers.md) |
| Live clients and informer reads | [Reads](docs/reads.md) |
| Admission on built-in and custom resources | [Admission](docs/admission.md) |
| Manifests, RBAC, TLS and deployment | [Applications](docs/operators.md) |
| Executable controller/operator examples | [Patterns](docs/patterns.md) |
| Caching, leadership and observability | [Caching](docs/caching.md), [runtime](docs/runtime.md) |
| Kubernetes integration tests | [Testing](docs/testing.md) |
| Existing model packages | [Integrations](docs/integrations.md) |

The [Widget demo](examples/widgets/README.md) builds and deploys a complete operator
with a CRD, ConfigMap, Deployment, Service, readiness and HTTPS admission.

Licensed under [Apache-2.0](LICENSE).
