Skip to main content

The ops library

CI Status

The ops library is a Python framework for developing and testing Kubernetes and machine charms. While charms can be written in any language, ops defines the latest standard, and charmers are encouraged to use Python with ops for all charms. The library is an official component of the Charm SDK, itself a part of the Juju universe.

  • ops is available on PyPI.
  • Version 2.x of ops requires Python 3.8 or above.
  • Read our docs for tutorials, how-to guides, the library reference, and more.

Give it a try

Let's use ops to build a Kubernetes charm:

Set up

See Juju | Set things up.
Choose the automatic track and MicroK8s.

Write your charm

On your Multipass VM, create a charm directory and use Charmcraft to initialise your charm file structure:

mkdir ops-example
cd ops-example
charmcraft init

This has created a standard charm directory structure:

$ ls -R
.:
CONTRIBUTING.md  README.md        pyproject.toml    src    tox.ini
LICENSE          charmcraft.yaml  requirements.txt  tests

./src:
charm.py

./tests:
integration  unit

./tests/integration:
test_charm.py

./tests/unit:
test_charm.py

Things to note:

  • The charmcraft.yaml file shows that what we have is an example charm called ops-example, which uses an OCI image resource httpbin from kennethreitz/httpbin.

  • The requirements.txt file lists the version of ops to use.

  • The src/charm.py file imports ops and uses ops constructs to create a charm class OpsExampleCharm, observe Juju events, and pair them to event handlers:

import ops

class OpsExampleCharm(ops.CharmBase):
    """Charm the service."""

    def __init__(self, *args):
        super().__init__(*args)
        self.framework.observe(self.on['httpbin'].pebble_ready, self._on_httpbin_pebble_ready)
        self.framework.observe(self.on.config_changed, self._on_config_changed)

    def _on_httpbin_pebble_ready(self, event: ops.PebbleReadyEvent):
        """Define and start a workload using the Pebble API.

        Change this example to suit your needs. You'll need to specify the right entrypoint and
        environment configuration for your specific workload.

        Learn more about interacting with Pebble at
            https://ops.readthedocs.io/en/latest/reference/pebble.html
        """
        # Get a reference the container attribute on the PebbleReadyEvent
        container = event.workload
        # Add initial Pebble config layer using the Pebble API
        container.add_layer("httpbin", self._pebble_layer, combine=True)
        # Make Pebble reevaluate its plan, ensuring any services are started if enabled.
        container.replan()
        # Learn more about statuses at
        # https://documentation.ubuntu.com/juju/3.6/reference/status/
        self.unit.status = ops.ActiveStatus()

See more: ops.PebbleReadyEvent

  • The tests/unit/test_charm.py file imports ops.testing and uses it to set up a unit test:
import ops
from ops import testing

from charm import OpsExampleCharm


def test_httpbin_pebble_ready():
    # Arrange:
    ctx = testing.Context(OpsExampleCharm)
    container = testing.Container("httpbin", can_connect=True)
    state_in = testing.State(containers={container})

    # Act:
    state_out = ctx.run(ctx.on.pebble_ready(container), state_in)

    # Assert:
    updated_plan = state_out.get_container(container.name).plan
    expected_plan = {
        "services": {
            "httpbin": {
                "override": "replace",
                "summary": "httpbin",
                "command": "gunicorn -b 0.0.0.0:80 httpbin:app -k gevent",
                "startup": "enabled",
                "environment": {"GUNICORN_CMD_ARGS": "--log-level info"},
            }
        },
    }
    assert expected_plan == updated_plan
    assert (
        state_out.get_container(container.name).service_statuses["httpbin"]
        == ops.pebble.ServiceStatus.ACTIVE
    )
    assert state_out.unit_status == testing.ActiveStatus()

See more: ops.testing

Explore further, start editing the files, or skip ahead and pack the charm:

charmcraft pack

If you didn't take any wrong turn or simply left the charm exactly as it was, this has created a file called ops-example_ubuntu-22.04-amd64.charm (the architecture bit may be different depending on your system's architecture). Use this name and the resource from the metadata.yaml to deploy your example charm to your local MicroK8s cloud:

juju deploy ./ops-example_ubuntu-22.04-amd64.charm --resource httpbin-image=kennethreitz/httpbin

Congratulations, you’ve just built your first Kubernetes charm using ops!

Clean up

See Juju | Tear things down.
Choose the automatic track.

Next steps

Download files

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

Source Distribution

ops-2.23.4.tar.gz (538.4 kB view details)

Uploaded Source

Built Distribution

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

ops-2.23.4-py3-none-any.whl (191.1 kB view details)

Uploaded Python 3

File details

Details for the file ops-2.23.4.tar.gz.

File metadata

  • Download URL: ops-2.23.4.tar.gz
  • Upload date:
  • Size: 538.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ops-2.23.4.tar.gz
Algorithm Hash digest
SHA256 0d6768e1ecd1a6e762e8c279b50e93c92d22190ba7a42cd8a579e3be4ebd6220
MD5 4e07260c70d81e3ba30e85064a6264b8
BLAKE2b-256 d6d6d292d085f4320d99121d2cdd3a6f57d4dcf3e0377cec9f36f2eabb4e15c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ops-2.23.4.tar.gz:

Publisher: publish-ops.yaml on canonical/operator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ops-2.23.4-py3-none-any.whl.

File metadata

  • Download URL: ops-2.23.4-py3-none-any.whl
  • Upload date:
  • Size: 191.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ops-2.23.4-py3-none-any.whl
Algorithm Hash digest
SHA256 c8a6cd08cb71b83029250f7265658194790d73120d655818ad59a9fcc127d2e4
MD5 3dd78d6ed7dcbf20ed238139cb469c9d
BLAKE2b-256 9a1f7a64706f0904d463b3d221308049a8389b02273c0b64de7e2de1c56f68bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ops-2.23.4-py3-none-any.whl:

Publisher: publish-ops.yaml on canonical/operator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

Supported by

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