Skip to content

Commit

Permalink
docs: add top-level intro and module-level intros (canonical#1320)
Browse files Browse the repository at this point in the history
Docs: Ops: Add top-level intro, clean up ops.module intro in light of
that, flesh out ops.pebble and ops.testing intros a bit more

https://warthogs.atlassian.net/browse/CHARMTECH-183

- [x] "home page" library reference
- [x] ops module
- [x] ops.main entry point
- [x] ops.pebble module
- [x] ops.testing module
  • Loading branch information
dimaqq authored and tonyandrewmeyer committed Oct 4, 2024
1 parent ea3ea4c commit f590ecc
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 24 deletions.
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@

## Features

* `StopEvent`, `RemoveEvent`, and all `LifeCycleEvent`s are no longer deferrable, and will raise a `RuntimeError` if `defer()` is called on the event object (#1122)
* `StopEvent`, `RemoveEvent`, and all `LifecycleEvent`s are no longer deferrable, and will raise a `RuntimeError` if `defer()` is called on the event object (#1122)
* Add `ActionEvent.id`, exposing the JUJU_ACTION_UUID environment variable (#1124)
* Add support for creating `pebble.Plan` objects by passing in a `pebble.PlanDict`, the
ability to compare two `Plan` objects with `==`, and the ability to create an empty Plan with `Plan()` (#1134)
Expand Down
30 changes: 30 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,45 @@
ops library API reference
=========================

The `ops` library is a Python framework for writing and testing Juju charms.

See more: `Charm SDK documentation <https://juju.is/docs/sdk>`_

The library provides:

- :ref:`ops_main_entry_point`, used to initialise and run your charm;
- :ref:`ops_module`, the API to respond to Juju events and manage the application;
- :ref:`ops_pebble_module`, the Pebble client, a low-level API for Kubernetes containers;
- :ref:`ops_testing_module`, the framework for unit testing charms in a simulated environment;

You can structure your charm however you like, but with the `ops` library, you
get a framework that promotes consistency and readability by following best
practices. It also helps you organise your code better by separating different
aspects of the charm, such as managing the application’s state, handling
integrations with other services, and making the charm easier to test.


.. toctree::
:maxdepth: 2
:caption: Contents:


.. _ops_module:

ops module
==========

.. automodule:: ops
:exclude-members: main


.. _ops_main_entry_point:

ops.main entry point
====================

The main entry point to initialise and run your charm.

.. autofunction:: ops.main


Expand All @@ -25,12 +51,16 @@ legacy main module
:noindex:


.. _ops_pebble_module:

ops.pebble module
=================

.. automodule:: ops.pebble


.. _ops_testing_module:

ops.testing module
==================

Expand Down
47 changes: 29 additions & 18 deletions ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,42 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""The ops library: a Python framework for writing Juju charms.
"""The API to respond to Juju events and manage the application.
The ops library is a Python framework (`available on PyPI`_) for developing
and testing Juju charms in a consistent way, using standard Python constructs
to allow for clean, maintainable, and reusable code.
This module provides code freatures to your charm, including:
A charm is an operator -- business logic encapsulated in a reusable software
package that automates every aspect of an application's life.
- :class:`~ops.CharmBase`, the base class for charms and :class:`~ops.Object`,
the base class for charm libraries.
- :class:`~ops.framework.EventBase` class and individual event types, like
the :class:`~ops.ActionEvent` class.
- :class:`~ops.Framework` class, accessible as ``self.framework`` in a charm,
the main interface for the charm to `ops` library infrastructure, including:
Charms written with ops support Kubernetes using Juju's "sidecar charm"
pattern, as well as charms that deploy to Linux-based machines and containers.
- :attr:`~ops.Framework.on` shorthand property used to
:meth:`~ops.Framework.observe` and react to Juju events.
- :attr:`~ops.Framework.model` attribute to get hold of the Model instance.
Charms should do one thing and do it well. Each charm drives a single
application and can be integrated with other charms to deliver a complex
system. A charm handles creating the application in addition to scaling,
configuration, optimisation, networking, service mesh, observability, and other
day-2 operations specific to the application.
- :class:`~ops.model.Model` class that represents the Juju model, accessible as
``self.model`` in a charm, including:
The ops library is part of the Charm SDK (the other part being Charmcraft).
Full developer documentation for the Charm SDK is available at
https://juju.is/docs/sdk.
- :attr:`~ops.Model.app` attribute, representing the application associated
with the charm.
- :attr:`~ops.Model.unit` attribute, representing the unit of the application
the charm is running on.
- :attr:`~ops.Model.relations` attribute, which provides access to relations
(integrations) defined in the charm, allowing interaction with other applications.
To learn more about Juju, visit https://juju.is/docs/olm.
- :class:`~ops.Container` class to control Kubernetes workloads, including:
.. _available on PyPI: https://pypi.org/project/ops/
- :meth:`~ops.Container.add_layer` and :meth:`~ops.Container.replan` methods
to update Pebble configuration.
- :meth:`~ops.Container.pull` and :meth:`~ops.Container.push` methods to copy
data to and from a container, respectively.
- :meth:`~ops.Container.exec` method to run arbitrary commands inside the
container.
- :class:`~ops.StatusBase` class and individual status types, like the
:class:`~ops.ActiveStatus` class.
"""

# The "from .X import Y" imports below don't explicitly tell Pyright (or MyPy)
Expand Down
6 changes: 5 additions & 1 deletion ops/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,11 @@ def __getattr__(self, name: str) -> BoundEvent:


class LifecycleEvent(EventBase):
"""Events tied to the lifecycle of the Framework object."""
"""Events tied to the lifecycle of the Framework object.
Note: Here, "lifecycle" was poorly named and has nothing to do with the
Juju [application] lifecycle.
"""

def defer(self) -> NoReturn:
"""Lifecycle events are not deferrable like other events.
Expand Down
6 changes: 5 additions & 1 deletion ops/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2317,7 +2317,11 @@ def start(self, *service_names: str):
self._pebble.start_services(service_names)

def restart(self, *service_names: str):
"""Restart the given service(s) by name."""
"""Restart the given service(s) by name.
Listed running services will be stopped and restarted, and listed stopped
services will be started.
"""
if not service_names:
raise TypeError('restart expected at least 1 argument, got 0')

Expand Down
19 changes: 17 additions & 2 deletions ops/pebble.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Client for the Pebble API (HTTP over Unix socket).
"""Client for the Pebble API.
For a command-line interface for local testing, see test/pebble_cli.py.
This module provides a way to interact with Pebble, including:
- :class:`~ops.pebble.Client`; communicates directly with the Pebble API.
- :class:`~ops.pebble.Layer` class to define Pebble configuration layers,
including:
- :class:`~ops.pebble.Check` class to represent Pebble checks.
- :class:`~ops.pebble.LogTarget` class to represent Pebble log targets.
- :class:`~ops.pebble.Service` class to represent Pebble service descriptions.
For a command-line interface for local testing, see ``test/pebble_cli.py``.
See more: `Pebble documentation <https://canonical-pebble.readthedocs-hosted.com/>`_
"""

from __future__ import annotations
Expand Down Expand Up @@ -2187,6 +2199,9 @@ def restart_services(
) -> ChangeID:
"""Restart services by name and wait (poll) for them to be started.
Listed running services will be stopped and restarted, and listed stopped
services will be started.
Args:
services: Non-empty list of services to restart.
timeout: Seconds before restart change is considered timed out (float). If
Expand Down
20 changes: 19 additions & 1 deletion ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,26 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Framework for unit testing charms in a simulated Juju environment.
"""Infrastructure to build unit tests for charms using the ops library."""
The module includes:
- :class:`ops.testing.Harness`, a class to set up the simulated environment,
that provides:
- :meth:`~ops.testing.Harness.add_relation` method, to declare a relation
(integration) with another app.
- :meth:`~ops.testing.Harness.begin` and :meth:`~ops.testing.Harness.cleanup`
methods to start and end the testing lifecycle.
- :meth:`~ops.testing.Harness.evaluate_status` method, which aggregates the
status of the charm after test interactions.
- :attr:`~ops.testing.Harness.model` attribute, which exposes e.g. the
:attr:`~ops.Model.unit` attribute for detailed assertions on the unit's state.
.. note::
Unit testing is only one aspect of a comprehensive testing strategy. For more
on testing charms, see `Charm SDK | Testing <https://juju.is/docs/sdk/testing>`_.
"""

from ._private.harness import (
ActionFailed,
Expand Down

0 comments on commit f590ecc

Please sign in to comment.