Skip to main content

Pythonic Kubernetes DSL — As powerful as Helm, as easy as Pulumi, as readable as Python

Project description

bow-cli

Pythonic Kubernetes DSL — As powerful as Helm, as easy as Pulumi, as readable as Python.

with Deployment("api", replicas=3):
    with Container("api", image="myorg/api:v2"):
        Port(8080)
        EnvVar("DB_HOST", "postgresql")
        Resources(cpu="250m", memory="256Mi")
        Probe("readiness", http_get={"path": "/health", "port": 8080})
    Service(port=8080)

Installation

One-line install (recommended)

Works on macOS and Linux. No manual venv activation needed — just install and use.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/getbow/bow/main/install.sh)"

This will:

  • Detect your platform and find Python 3.11+
  • Create an isolated environment at ~/.bow/
  • Place the bow command on your PATH (~/.local/bin/bow)
  • Update your shell profile (~/.zshrc, ~/.bashrc, etc.)

After installation, open a new terminal and run:

bow --help

Options

Customize the installation via environment variables:

# Install a specific version
BOW_VERSION=0.3.1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/getbow/bow/main/install.sh)"

# Install from PyPI (when available) instead of GitHub
BOW_SOURCE=pypi /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/getbow/bow/main/install.sh)"

# Custom install directory
BOW_DIR=/opt/bow /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/getbow/bow/main/install.sh)"

# Don't modify shell profile
BOW_NO_MODIFY_PATH=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/getbow/bow/main/install.sh)"

Uninstall

rm -rf ~/.bow ~/.local/bin/bow

pip install (alternative)

pip install bow-cli

Quick Start

Deploy with CLI

# Single chart
bow up postgresql
bow up postgresql --set replicas=3 --set storage=50Gi
bow up postgresql -f values.yaml

# With stack file
bow up -f stack.yaml
bow up -f stack.yaml -f values.prod.yaml

# YAML preview (without applying)
bow template postgresql --set metrics.enabled=true

Stack file

# stack.yaml
apiVersion: bow.io/v1
kind: Stack
metadata:
  name: my-project
  namespace: my-project

components:
  - chart: postgresql
    name: db
    values:
      database: myapp
      storage: 50Gi

  - chart: redis
    name: cache
    values:
      storage: 5Gi

  - chart: redmine
    name: redmine
    values:
      postgresql:
        enabled: false
        name: "${db.host}"

Environment overlay

# values.prod.yaml
components:
  db:
    values:
      replicas: 3
      storage: 200Gi
  redmine:
    values:
      replicas: 5
      ingress:
        enabled: true
        host: redmine.example.com
        tls: true
bow up -f stack.yaml -f values.prod.yaml

Three Usage Layers

Layer 1: CLI one-liner

bow up postgresql --set storage=50Gi

Layer 2: YAML Stack

Declarative component architecture without any Python knowledge:

bow up -f stack.yaml -f values.prod.yaml --set components.db.values.replicas=5

Layer 3: Python Chart Development

Chart authors define reusable components using contextlib:

from contextlib import contextmanager
from bow.chart.base import Chart
from bow.core.resources import *

@contextmanager
def my_container(name, image, port=8080):
    with Container(name, image=image):
        Port(port, name="http")
        Probe("readiness", http_get={"path": "/health", "port": port})
        yield  # can be extended inside the with block

class MyChart(Chart):
    name = "myapp"
    version = "1.0.0"

    def render(self, values):
        with Deployment(values["name"], replicas=values.get("replicas", 1)):
            with my_container(values["name"], values["image"]):
                EnvVar("DB_HOST", values.get("db_host", "localhost"))
            Service(port=8080)

Resource Reference

with (context manager) — can have children

with Deployment("api", replicas=3):          # Pod spec parent
    with Container("api", image="app:v1"):   # Leaf parent
        ...
    with Service(type="NodePort"):           # Multi-port mode
        ServicePort(80, name="http")
        ServicePort(443, name="https")

with StatefulSet("db", replicas=3):          # StatefulSet
    ...

with ConfigMap("cfg"):                       # Key-value store
    Data("key", "value")

with Secret("creds"):                        # Encoded data
    Data("password", "s3cret")

with Ingress("ing", host="app.example.com"): # Parametric
    IngressRule("/", "web", 80)
    IngressRule("/api", "api", 8080)

with CronJob("backup", schedule="0 2 * * *"):
    with Container("backup", image="backup:v1"):
        ...

Leaf — no children, plain function call

Port(8080, name="http")
EnvVar("DB_HOST", "localhost")
EnvVar("PASSWORD", secret_ref="my-secret", secret_key="pass")
Resources(cpu="250m", memory="256Mi", limits_cpu="500m", limits_memory="512Mi")
VolumeMount("/data", "my-vol", read_only=True)
Probe("liveness", http_get={"path": "/health", "port": 8080})
Service(port=80)                              # Simple mode (leaf)
Data("key", "value")                          # Inside ConfigMap/Secret
IngressRule("/", "web", 80)                   # Inside Ingress
PersistentVolumeClaim("data", size="50Gi")
EmptyDirVolume("tmp")
ConfigMapVolume("cfg", "my-config")
SecretVolume("certs", "tls-certs")

Chart Development

Each chart is a pip package:

bow-myapp/
├── pyproject.toml
├── src/bow_myapp/
│   ├── __init__.py      # MyChart class
│   └── defaults.yaml    # Default values
# pyproject.toml
[project]
name = "bow-myapp"
version = "1.0.0"
dependencies = ["bow-cli>=0.1.0"]

[project.entry-points."bow.charts"]
myapp = "bow_myapp:MyChart"

Dependency

# bow-redmine/pyproject.toml
dependencies = [
    "bow-cli>=0.1.0",
    "bow-postgresql>=16.0.0",
]
from bow.chart.dependency import ChartDep

class RedmineChart(Chart):
    requires = [
        ChartDep("postgresql", deploy=True, condition="postgresql.enabled"),
    ]

CLI Commands

bow up <chart> [flags]       # Deploy
bow template <chart> [flags] # YAML preview
bow list                     # Installed charts
bow inspect <chart>          # Chart details + defaults

Flags

Flag Description
-f <file> Values or stack file (multiple allowed)
--set key=val Value override
-n <namespace> Kubernetes namespace
--create-namespace Create namespace if it doesn't exist
--dry-run kubectl dry-run
-o <file> Output file (template)

Value precedence

defaults.yaml → -f values.yaml → -f values.prod.yaml → --set key=val

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bow_cli-0.4.4.tar.gz (112.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bow_cli-0.4.4-py3-none-any.whl (55.9 kB view details)

Uploaded Python 3

File details

Details for the file bow_cli-0.4.4.tar.gz.

File metadata

  • Download URL: bow_cli-0.4.4.tar.gz
  • Upload date:
  • Size: 112.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bow_cli-0.4.4.tar.gz
Algorithm Hash digest
SHA256 c056b1cb169d64bb7bb11c6c665e743c09033638dd4fd39706e7788b7f34324b
MD5 61c95b90ebf913e303f135643b91b64a
BLAKE2b-256 027518026de641f20059c560c91d2e9655c3ca14681424cb2c5922f0fdb6fda6

See more details on using hashes here.

File details

Details for the file bow_cli-0.4.4-py3-none-any.whl.

File metadata

  • Download URL: bow_cli-0.4.4-py3-none-any.whl
  • Upload date:
  • Size: 55.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bow_cli-0.4.4-py3-none-any.whl
Algorithm Hash digest
SHA256 2b57ec0273eb0aae6dcca4fdfc17f1a6a6225b2fbab5e8f2e336b96b992ac21a
MD5 c0ded0cb5e1789a7a6a67d1558cec642
BLAKE2b-256 1fe2630cffb57a78896a5faa4d0c39ebcfcdd62a16782d8d89e5981b1af695e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page